Overview
Exploration of all the data collected on the presence points + randomly generated background points
A note to anyone who might happen to stumble across this… I am a beginner in R and have had no exposure to similar languages. I don’t know what I’m doing. The code herein is unlikely to be elegant and there are probably more efficient ways of running the code.
Built with ‘r getRversion()’.
Package dependencies
You can load them using the following code which uses a function called ipak. Note this function checks to see if the packages are installed first. The “include=FALSE” supresses the package installation text appearing in the document…
read in all data
and subset into background and presences
presab <- read.csv("../output/bio/presab_10k.csv", header = TRUE)
presence <- subset(presab, occurrence == "1")
background <- subset(presab, occurrence == "0")
Update: Who sampled in which year and which month:
year
inst_by_yr <- with(presence, table(year, institutioncode))
write.csv(inst_by_yr, file = "../output/bio/institutioncode_by_yr.csv")
inst_by_yr
institutioncode
year ARC DFOCENARC DFOGulf DFOISDM DFOMTMS DFONL DFOQC MaineDMR NEFSC ROM
1998 1 0 45 1 20 551 1 0 1 0
1999 0 0 78 1 71 466 0 0 0 0
2000 2 0 82 1 57 502 0 0 0 0
2001 0 0 49 1 43 504 0 0 0 0
2002 7 0 95 1 49 467 0 0 0 0
2003 0 0 39 3 42 534 0 0 0 0
2004 0 0 72 2 24 621 156 0 0 0
2005 1 14 69 0 63 446 171 7 0 0
2006 3 11 73 4 71 447 192 6 0 0
2007 1 39 80 1 37 430 196 0 0 1
2008 0 10 74 4 38 450 212 0 0 0
2009 0 10 71 0 28 479 87 3 0 0
2010 1 9 89 0 42 498 77 0 0 0
2011 0 22 72 0 13 438 96 0 0 0
2012 0 8 76 0 10 0 103 0 0 0
2013 2 18 64 0 21 0 89 0 0 0
2014 1 19 92 0 6 0 0 0 0 0
2015 3 12 0 0 0 0 0 0 0 0
month
inst_by_mt <- with(presence, table(month, institutioncode))
write.csv(inst_by_mt, file = "../output/bio/institutioncode_by_mth.csv")
inst_by_mt
institutioncode
month ARC DFOCENARC DFOGulf DFOISDM DFOMTMS DFONL DFOQC MaineDMR NEFSC ROM
1 0 0 0 0 0 243 0 0 0 0
2 0 0 0 0 6 4 0 0 0 0
3 1 0 0 2 318 0 0 0 0 0
4 0 0 0 3 11 682 0 0 1 0
5 0 0 0 0 0 1015 2 8 0 0
6 0 0 0 0 0 1562 4 3 0 0
7 4 19 0 3 286 46 27 0 0 1
8 1 71 6 1 14 0 1332 0 0 0
9 8 20 1209 3 0 5 13 0 0 0
10 0 61 5 3 0 520 2 2 0 0
11 8 1 0 3 0 1722 0 3 0 0
12 0 0 0 1 0 1034 0 0 0 0
and just a year-month table
year_by_mt <- with(presence, table(year, month))
write.csv(year_by_mt, file = "../output/bio/year_by_mth.csv")
year_by_mt
month
year 1 2 3 4 5 6 7 8 9 10 11 12
1998 0 0 0 59 81 131 20 0 45 78 195 11
1999 0 0 46 42 61 152 25 0 78 10 145 57
2000 0 0 41 42 55 117 19 0 82 35 178 75
2001 0 5 24 69 77 100 15 0 49 24 86 148
2002 0 0 32 74 78 106 17 0 102 37 73 100
2003 54 0 23 70 91 127 19 0 40 35 54 105
2004 120 0 0 51 81 125 26 143 82 28 105 114
2005 17 4 28 22 66 106 39 181 70 46 149 43
2006 52 1 50 21 5 124 26 201 74 65 107 81
2007 0 0 20 52 52 93 70 200 80 37 96 85
2008 0 0 30 36 76 125 30 202 71 27 130 61
2009 0 0 10 66 144 55 8 83 73 33 159 47
2010 0 0 17 39 68 113 25 85 94 65 152 58
2011 0 0 0 54 90 95 11 108 67 63 103 50
2012 0 0 0 0 0 0 8 113 76 0 0 0
2013 0 0 0 0 0 0 27 94 64 7 2 0
2014 0 0 0 0 0 0 1 11 103 3 0 0
2015 0 0 0 0 0 0 0 4 8 0 3 0
environmental correlates
- Get the max, min, an mean values and add into a dataframe
Temperature
temp_depth_max <- max(presence$temp_depth, na.rm = TRUE)
temp_depth_min <- min(presence$temp_depth, na.rm = TRUE)
temp_depth_mean <- mean(presence$temp_depth, na.rm = TRUE)
temp_surface_max <- max(presence$temp_surface, na.rm = TRUE)
temp_surface_min <- min(presence$temp_surface, na.rm = TRUE)
temp_surface_mean <- mean(presence$temp_surface, na.rm = TRUE)
Salinity
sal_depth_max <- max(presence$salinity_depth, na.rm = TRUE)
sal_depth_min <- min(presence$salinity_depth, na.rm = TRUE)
sal_depth_mean <- mean(presence$salinity_depth, na.rm = TRUE)
sal_surface_max <- max(presence$salinity_surface, na.rm = TRUE)
sal_surface_min <- min(presence$salinity_surface, na.rm = TRUE)
sal_surface_mean <- mean(presence$salinity_surface, na.rm = TRUE)
Chl
chl_depth_max <- max(presence$chl_depth, na.rm = TRUE)
chl_depth_min <- min(presence$chl_depth, na.rm = TRUE)
chl_depth_mean <- mean(presence$chl_depth, na.rm = TRUE)
chl_surface_max <- max(presence$chl_surface, na.rm = TRUE)
chl_surface_min <- min(presence$chl_surface, na.rm = TRUE)
chl_surface_mean <- mean(presence$chl_surface, na.rm = TRUE)
O2
o2_depth_max <- max(presence$o2_depth, na.rm = TRUE)
o2_depth_min <- min(presence$o2_depth, na.rm = TRUE)
o2_depth_mean <- mean(presence$o2_depth, na.rm = TRUE)
o2_surface_max <- max(presence$o2_surface, na.rm = TRUE)
o2_surface_min <- min(presence$o2_surface, na.rm = TRUE)
o2_surface_mean <- mean(presence$o2_surface, na.rm = TRUE)
MLP
mlp_surface_max <- max(presence$mlp_surface, na.rm = TRUE)
mlp_surface_min <- min(presence$mlp_surface, na.rm = TRUE)
mlp_surface_mean <- mean(presence$mlp_surface, na.rm = TRUE)
SSH
ssh_surface_max <- max(presence$ssh_surface, na.rm = TRUE)
ssh_surface_min <- min(presence$ssh_surface, na.rm = TRUE)
ssh_surface_mean <- mean(presence$ssh_surface, na.rm = TRUE)
create matrix
td <- c(temp_depth_max, temp_depth_min, temp_depth_mean)
ts <- c(temp_surface_max, temp_surface_min, temp_surface_mean)
sd <- c(sal_depth_max, sal_depth_min, sal_depth_mean)
ss <- c(sal_surface_max, sal_surface_min, sal_surface_mean)
cd <- c(sal_depth_max, sal_depth_min, sal_depth_mean)
cs <- c(sal_surface_max, sal_surface_min, sal_surface_mean)
od <- c(o2_depth_max, o2_depth_min, o2_depth_mean)
os <- c(o2_surface_max, o2_surface_min, o2_surface_mean)
mlp <- c(mlp_surface_max, mlp_surface_min, mlp_surface_mean)
ssh <- c(ssh_surface_max, ssh_surface_min, ssh_surface_mean)
env_stats <- rbind(td, ts, sd, ss, cd, cs, od, os, mlp, ssh)
row.names(env_stats) <- c("Temp Depth", "Temp Surface", "Salinity Depth", "Salinity Surface", "Chl Depth", "Chl Surface", "Oxygen Depth", "Oxygen Surface", "MLP", "SSH")
colnames(env_stats) <- c("Max", "Min", "Mean")
write.csv(env_stats, "../output/env/env_correlates_basic_stats.csv", row.names = TRUE)
env_stats
Max Min Mean
Temp Depth 289.0834045 271.2114868 274.9217164
Temp Surface 293.3608093 271.6101074 280.4476878
Salinity Depth 35.5045395 22.1449070 33.4295117
Salinity Surface 34.3667259 13.5929441 30.2518319
Chl Depth 35.5045395 22.1449070 33.4295117
Chl Surface 34.3667259 13.5929441 30.2518319
Oxygen Depth 377.2959595 0.9998450 279.6701444
Oxygen Surface 385.2262878 238.3178253 315.1620514
MLP 108.2339201 10.6823719 18.1911518
SSH -0.2825949 -0.8503166 -0.5334292
Hmm some potentially suspicious values here in - Oxygen Depth min - mlp Max and maybe also - Salinity Depth min - Salinity Surface min - CHL depth min - CHL depth max
lets just see where these values appear and check the netcdf layers. Note I will check these values in cygwin using the cdo operator infov on the netcdfs (to ensure there was no issue with processing in R).
get the year and month these values appeared in
o2d_check_yr <- subset(presence$year, presence$o2_depth == o2_depth_min)
o2d_check_mth <- subset(presence$month, presence$o2_depth == o2_depth_min)
O2 depth min is in 2005_08
And value seems correct
mlp_check_yr <- subset(presence$year, presence$mlp_surface == mlp_surface_max)
mlp_check_mth <- subset(presence$month, presence$mlp_surface == mlp_surface_max)
mlp max in in 2007_12
And yes the value seems correct
sald_check_yr <- subset(presence$year, presence$salinity_depth == sal_depth_max)
sald_check_mth <- subset(presence$month, presence$salinity_depth == sal_depth_max)
year month 2001_05
also seems correct
sals_check_yr <- subset(presence$year, presence$salinity_surface == sal_surface_min)
sals_check_mth <- subset(presence$month, presence$salinity_surface == sal_surface_min)
year month 21998_06
ok again…
Leave the rest
simple plots of env. correlates
temperature
par(mfrow=c(1,2))
plot(presence$temp_depth, main = "Temp at Depth (Various)", ylab = "Kelvin")
plot(presence$temp_surface, main = "Temp at Surface", ylab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_simpleplot.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

Hmm not necessarily very helpful. But anyway, lets carry on
salinity
par(mfrow=c(1,2))
plot(presence$salinity_depth, main = "Salinity at Depth (Various)", ylab = "Practical Salinity Units")
plot(presence$salinity_surface, main = "Salinity at Surface", ylab = "Practical Salinity Units")
dev.copy(png,"../output/env/simple_plots/salinity_simpleplot.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

Chlorophyll
par(mfrow=c(1,2))
plot(presence$chl_depth, main = "Chl at Depth (Various)", ylab = "Chl (mmol.m-3)")
plot(presence$chl_surface, main = "Chl at Surface", ylab = "Chl (mmol.m-3)")
dev.copy(png,"../output/env/simple_plots/chl_simpleplot.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

O2
par(mfrow=c(1,2))
plot(presence$o2_depth, main = "Dissolved Oxygen at Depth (Various)", ylab = "Chl (mmol.m-3)")
plot(presence$o2_surface, main = "Dissolved Oxygen at Surface", ylab = "O2 (mmol.m-3)")
dev.copy(png,"../output/env/simple_plots/o2_simpleplot.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

mlp
plot(presence$mlp_surface, main = "Mixed Layer Thickness", ylab = "Depth (m)")
dev.copy(png,"../output/env/simple_plots/mlp_simpleplot.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

SSH
plot(presence$ssh_surface, main = "Sea Surface Height", ylab = "Height (m)")
dev.copy(png,"../output/env/simple_plots/ssh_simpleplot.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

XXX SAM - YOU WANT TO THINK ABOUT DOING THIS BY DEPTH RATHER THAN ALL DEPTHS)
unique_depths <- unique(presence$depthlayerno)
unique_depthdordered <- sort(unique_depths) #just puts the list in oder with no NA
length(unique_depthdordered)
[1] 39
ouch - 39 layers… a job for a boxplot probably
frequency plots of env. corr
temperature
hist(presence$temp_surface, main = "Temp at Surface", xlab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

hist(presence$temp_dept, main = "Temp at Depth", xlab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

chl
hist(presence$chl_surface, main = "Chlorophyll at Surface", xlab = "Chlorophyll Concentrations (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/chl_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

hist(presence$chl_depth, main = "Chlorophyll at Observation Depth", xlab = "Chlorophyll Concentrations (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/chl_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

salinity
hist(presence$salinity_surface, main = "Salinity at Surface", xlab = "Salinity Practical Salinity Unit (PSU)")
dev.copy(png, "../output/env/simple_plots/sal_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

hist(presence$salinity_depth, main = "Salinity at Observation Depth", xlab = "Salinity Practical Salinity Unit (PSU)")
dev.copy(png, "../output/env/simple_plots/sal_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

oxygen
hist(presence$o2_surface, main = "Dissolved Oxygen at Surface", xlab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/o2_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

hist(presence$o2_depth, main = "Dissolved Oxygen at Observation Depth", xlab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/o2_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

MLP
hist(presence$mlp, main = "Mixed Layer Thickness at Observation", xlab = "Mixed Layer Thickness (m)")
dev.copy(png, "../output/env/simple_plots/mlp_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ssh
hist(presence$ssh, main = "Sea Surface Height at Observation", xlab = "Sea Surface Height (m)")
dev.copy(png, "../output/env/simple_plots/ssh_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

simple boxplots of env. corr
Same as above but with boxplots (may provide some more useful info)
individual plots of each variable
par(mfrow=c(1,2))
boxplot(presence$chl_depth, main = "Chlorphyll at Depth (Various)", ylab = "mmol.m-3")
boxplot(presence$chl_surface, main = "Chlorphyll at Surface", ylab = "mmol.m-3")
dev.copy(png, "../output/env/simple_plots/chl_boxplot.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$temp_depth ~ presence$month, xlab = "month", ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth per Month")
dev.copy(png, "../output/env/simple_plots/temperature_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$chl_depth ~ presence$month, xlab = "month", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Observation Depth per Month")
dev.copy(png, "../output/env/simple_plots/chlorophyll_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$salinity_depth ~ presence$month, xlab = "month", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Observation Depth per Month")
dev.copy(png, "../output/env/simple_plots/salinity_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$o2_depth ~ presence$month, xlab = "month", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Observation Depth per Month")
dev.copy(png, "../output/env/simple_plots/o2_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$mlp_surface ~ presence$month, xlab = "month", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Observation per Month")
dev.copy(png, "../output/env/simple_plots/mlp_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$ssh_surface ~ presence$month, xlab = "month", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Observation per Month")
dev.copy(png, "../output/env/simple_plots/ssh_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$temp_depth ~ presence$year, xlab = "Year", ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth per Year")
dev.copy(png, "../output/env/simple_plots/temperature_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$chl_depth ~ presence$year, xlab = "Year", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Observation Depth per Year")
dev.copy(png, "../output/env/simple_plots/chl_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$salinity_depth ~ presence$year, xlab = "Year", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Observation Depth per Year")
dev.copy(png, "../output/env/simple_plots/salinity_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$o2_depth ~ presence$year, xlab = "Year", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Observation Depth per Year")
dev.copy(png, "../output/env/simple_plots/oxygen_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$mlp ~ presence$year, xlab = "Year", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Observation per Year")
dev.copy(png, "../output/env/simple_plots/mlp_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$ssh ~ presence$year, xlab = "Year", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Observation per Year")
dev.copy(png, "../output/env/simple_plots/ssh_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$temp_surface ~ presence$month, xlab = "month", ylab = "Temperature (Kelvin)", main = "Temperature at Observation (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/temperature_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$chl_surface ~ presence$month, xlab = "month", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Observation (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/chlorophyll_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$salinity_surface ~ presence$month, xlab = "month", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Observation (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/salinity_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$o2_surface ~ presence$month, xlab = "month", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Observation (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/o2_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$mlp_surface ~ presence$month, xlab = "month", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Observation per Month")
dev.copy(png, "../output/env/simple_plots/mlp_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$ssh_surface ~ presence$month, xlab = "month", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Observation per Month")
dev.copy(png, "../output/env/simple_plots/ssh_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$temp_surface ~ presence$year, xlab = "Year", ylab = "Temperature (Kelvin)", main = "Temperature at Observation (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/temperature_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$chl_surface ~ presence$year, xlab = "Year", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Observation (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/chl_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$salinity_surface ~ presence$year, xlab = "Year", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Observation (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/salinity_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(presence$o2_surface ~ presence$year, xlab = "Year", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Observation (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/oxygen_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

background points
environmental correlates
- Get the max, min, an mean values and add into a dataframe
Temperature
temp_depth_max_back <- max(background$temp_depth, na.rm = TRUE)
temp_depth_min_back <- min(background$temp_depth, na.rm = TRUE)
temp_depth_mean_back <- mean(background$temp_depth, na.rm = TRUE)
temp_surface_max_back <- max(background$temp_surface, na.rm = TRUE)
temp_surface_min_back <- min(background$temp_surface, na.rm = TRUE)
temp_surface_mean_back <- mean(background$temp_surface, na.rm = TRUE)
Salinity
sal_depth_max_back <- max(background$salinity_depth, na.rm = TRUE)
sal_depth_min_back <- min(background$salinity_depth, na.rm = TRUE)
sal_depth_mean_back <- mean(background$salinity_depth, na.rm = TRUE)
sal_surface_max_back <- max(background$salinity_surface, na.rm = TRUE)
sal_surface_min_back <- min(background$salinity_surface, na.rm = TRUE)
sal_surface_mean_back <- mean(background$salinity_surface, na.rm = TRUE)
Chl
chl_depth_max_back <- max(background$chl_depth, na.rm = TRUE)
chl_depth_min_back <- min(background$chl_depth, na.rm = TRUE)
chl_depth_mean_back <- mean(background$chl_depth, na.rm = TRUE)
chl_surface_max_back <- max(background$chl_surface, na.rm = TRUE)
chl_surface_min_back <- min(background$chl_surface, na.rm = TRUE)
chl_surface_mean_back <- mean(background$chl_surface, na.rm = TRUE)
O2
o2_depth_max_back <- max(background$o2_depth, na.rm = TRUE)
o2_depth_min_back <- min(background$o2_depth, na.rm = TRUE)
o2_depth_mean_back <- mean(background$o2_depth, na.rm = TRUE)
o2_surface_max_back <- max(background$o2_surface, na.rm = TRUE)
o2_surface_min_back <- min(background$o2_surface, na.rm = TRUE)
o2_surface_mean_back <- mean(background$o2_surface, na.rm = TRUE)
MLP
mlp_surface_max_back <- max(background$mlp_surface, na.rm = TRUE)
mlp_surface_min_back <- min(background$mlp_surface, na.rm = TRUE)
mlp_surface_mean_back <- mean(background$mlp_surface, na.rm = TRUE)
SSH
ssh_surface_max_back <- max(background$ssh_surface, na.rm = TRUE)
ssh_surface_min_back <- min(background$ssh_surface, na.rm = TRUE)
ssh_surface_mean_back <- mean(background$ssh_surface, na.rm = TRUE)
create matrix
tdb <- c(temp_depth_max_back, temp_depth_min_back, temp_depth_mean_back)
tsb <- c(temp_surface_max_back, temp_surface_min_back, temp_surface_mean_back)
sdb <- c(sal_depth_max_back, sal_depth_min_back, sal_depth_mean_back)
ssb <- c(sal_surface_max_back, sal_surface_min_back, sal_surface_mean_back)
cdb <- c(sal_depth_max_back, sal_depth_min_back, sal_depth_mean_back)
csb <- c(sal_surface_max_back, sal_surface_min_back, sal_surface_mean_back)
odb <- c(o2_depth_max_back, o2_depth_min_back, o2_depth_mean_back)
osb <- c(o2_surface_max_back, o2_surface_min_back, o2_surface_mean_back)
mlpb <- c(mlp_surface_max_back, mlp_surface_min_back, mlp_surface_mean_back)
sshb <- c(ssh_surface_max_back, ssh_surface_min_back, ssh_surface_mean_back)
env_stats_back <- rbind(tdb, tsb, sdb, ssb, cdb, csb, odb, osb, mlpb, sshb)
row.names(env_stats_back) <- c("Temp Depth", "Temp Surface", "Salinity Depth", "Salinity Surface", "Chl Depth", "Chl Surface", "Oxygen Depth", "Oxygen Surface", "MLP", "SSH")
colnames(env_stats_back) <- c("Max", "Min", "Mean")
write.csv(env_stats_back, "../output/env/env_correlates_background_basic_stats.csv", row.names = TRUE)
env_stats_back
Max Min Mean
Temp Depth 296.6814000 270.4851000 276.9213399
Temp Surface 298.0739000 271.0959000 278.3042248
Salinity Depth 36.1154400 13.4615900 33.2171443
Salinity Surface 35.7264900 12.5724900 32.2697238
Chl Depth 36.1154400 13.4615900 33.2171443
Chl Surface 35.7264900 12.5724900 32.2697238
Oxygen Depth 460.2821000 0.9636452 303.3679603
Oxygen Surface 405.9796000 207.9546000 320.6152836
MLP 2237.7090000 8.5859600 39.0529201
SSH -0.2319994 -1.2355570 -0.6758784
temperature
par(mfrow=c(1,2))
plot(background$temp_depth, main = "Background Points Temp at Depth (Various)", ylab = "Kelvin")
plot(background$temp_surface, main = "Background Points Temp at Surface", ylab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

salinity
par(mfrow=c(1,2))
plot(background$salinity_depth, main = "Background Points Salinity at Depth (Various)", ylab = "Practical Salinity Units")
plot(background$salinity_surface, main = "Background Points Salinity at Surface", ylab = "Practical Salinity Units")
dev.copy(png,"../output/env/simple_plots/salinity_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

Chlorophyll
par(mfrow=c(1,2))
plot(background$chl_depth, main = "Background Points Chl at Depth (Various)", ylab = "Chl (mmol.m-3)")
plot(background$chl_surface, main = "Background Points Chl at Surface", ylab = "Chl (mmol.m-3)")
dev.copy(png,"../output/env/simple_plots/chl_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

O2
par(mfrow=c(1,2))
plot(background$o2_depth, main = "Background Points Dissolved Oxygen at Depth (Various)", ylab = "Chl (mmol.m-3)")
plot(background$o2_surface, main = "Background Points Dissolved Oxygen at Surface", ylab = "O2 (mmol.m-3)")
dev.copy(png,"../output/env/simple_plots/o2_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

mlp
plot(background$mlp_surface, main = "Background Points Mixed Layer Thickness", ylab = "Depth (m)")
dev.copy(png,"../output/env/simple_plots/mlp_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

SSH
plot(background$ssh_surface, main = "Background Points Sea Surface Height", ylab = "Height (m)")
dev.copy(png,"../output/env/simple_plots/ssh_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

frequency plots of env. corr
temperature
hist(background$temp_surface, main = "Background Temp at Surface", xlab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

hist(background$temp_dept, main = "Background Temp at Depth", xlab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_background_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

chl
hist(background$chl_surface, main = "Background Chlorophyll at Surface", xlab = "Chlorophyll Concentrations (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/chl_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

hist(background$chl_depth, main = "Background Chlorophyll at Observation Depth", xlab = "Chlorophyll Concentrations (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/chl_background_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

salinity
hist(background$salinity_surface, main = "Background Salinity at Surface", xlab = "Salinity Practical Salinity Unit (PSU)")
dev.copy(png, "../output/env/simple_plots/sal_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

hist(background$salinity_depth, main = "Background Salinity at Observation Depth", xlab = "Salinity Practical Salinity Unit (PSU)")
dev.copy(png, "../output/env/simple_plots/sal_background_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

oxygen
hist(background$o2_surface, main = "Background Dissolved Oxygen at Surface", xlab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/o2_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

hist(background$o2_depth, main = "Background Dissolved Oxygen at Observation Depth", xlab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/o2_background_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

MLP
hist(background$mlp, main = "Background Mixed Layer Thickness at Observation", xlab = "Mixed Layer Thickness (m)")
dev.copy(png, "../output/env/simple_plots/mlp_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ssh
hist(background$ssh, main = "Background Sea Surface Height at Observation", xlab = "Sea Surface Height (m)")
dev.copy(png, "../output/env/simple_plots/ssh_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

simple boxplots of env. corr
Same as above but with boxplots (may provide some more useful info)
temperature
boxplot(background$temp_depth ~ background$month, xlab = "month", ylab = "Temperature (Kelvin)", main = "Temperature at Background Depth per Month")
dev.copy(png, "../output/env/simple_plots/temperature_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$chl_depth ~ background$month, xlab = "month", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Background Depth per Month")
dev.copy(png, "../output/env/simple_plots/chlorophyll_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$salinity_depth ~ background$month, xlab = "month", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Background Depth per Month")
dev.copy(png, "../output/env/simple_plots/salinity_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$o2_depth ~ background$month, xlab = "month", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Background Depth per Month")
dev.copy(png, "../output/env/simple_plots/o2_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$mlp_surface ~ background$month, xlab = "month", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Background per Month")
dev.copy(png, "../output/env/simple_plots/mlp_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$ssh_surface ~ background$month, xlab = "month", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Background per Month")
dev.copy(png, "../output/env/simple_plots/ssh_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$temp_depth ~ background$year, xlab = "Year", ylab = "Temperature (Kelvin)", main = "Temperature at Background Depth per Year")
dev.copy(png, "../output/env/simple_plots/temperature_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$chl_depth ~ background$year, xlab = "Year", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Background Depth per Year")
dev.copy(png, "../output/env/simple_plots/chl_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$salinity_depth ~ background$year, xlab = "Year", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Background Depth per Year")
dev.copy(png, "../output/env/simple_plots/salinity_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$o2_depth ~ background$year, xlab = "Year", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Background Depth per Year")
dev.copy(png, "../output/env/simple_plots/oxygen_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$mlp ~ background$year, xlab = "Year", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Background per Year")
dev.copy(png, "../output/env/simple_plots/mlp_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$ssh ~ background$year, xlab = "Year", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Background per Year")
dev.copy(png, "../output/env/simple_plots/ssh_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$temp_surface ~ background$month, xlab = "month", ylab = "Temperature (Kelvin)", main = "Temperature at Background (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/temperature_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$chl_surface ~ background$month, xlab = "month", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Background (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/chlorophyll_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$salinity_surface ~ background$month, xlab = "month", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Background (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/salinity_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$o2_surface ~ background$month, xlab = "month", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Background (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/o2_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$mlp_surface ~ background$month, xlab = "month", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Background per Month")
dev.copy(png, "../output/env/simple_plots/mlp_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$ssh_surface ~ background$month, xlab = "month", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Background per Month")
dev.copy(png, "../output/env/simple_plots/ssh_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$temp_surface ~ background$year, xlab = "Year", ylab = "Temperature (Kelvin)", main = "Temperature at Background (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/temperature_background_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$chl_surface ~ background$year, xlab = "Year", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Background (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/chl_background_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$salinity_surface ~ background$year, xlab = "Year", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Background (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/salinity_background_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

boxplot(background$o2_surface ~ background$year, xlab = "Year", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Background (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/oxygen_background_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

correlations between background points
check to see if there are any correlations in the env. variables for the background points
first subset the env.correlate columns (you don’t need everything)
background_env <- subset(background, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth))
background_env_cor <- cor(background_env, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(background_env_cor, "../output/env/background_env_corr.csv", row.names = TRUE)
background_corrplot <- corrplot(background_env_cor , method = "color", type = "upper", order = "alphabet", tl.cex = 0.8)
dev.copy(png,"../output/env/simple_plots/background_envcorr.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

to get some density plots all in one graphic, you need to change chunk output to in console, then go to the plot tab, make it fill the screen, then run then make bigger then save :( (probably a better way - this seems to be an issue with RStudio)
par(mfrow=c(4,4))
for(i in 1:16){
plot(density(background_env[,i], na.rm=T), main = names(background_env)[i])
}

PUT THE CHUNK OUTPUT BACK TO INLINE
add nafo region and gear type into the mix CANT!!
first subset the env.correlate columns + bottom_depth (you don’t need everything)
background_envbotdepth <- subset(background, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
background_envbotdepth_cor <- cor(background_envbotdepth, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(background_envbotdepth_cor, "../output/env/background_envbotdepth_cor.csv", row.names = TRUE)
background_corrplot <- corrplot(background_envbotdepth_cor , method = "color", type = "upper", order = "alphabet", tl.cex = 0.8)
dev.copy(png,"../output/env/simple_plots/background_envbotdepth_cor.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

correlations between presence points
check to see if there are any correlations in the env. variables
first subset the env.correlate columns (you don’t need everything) then use cor to get the correlation values, and then corrplot for a visual
pres_env <- subset(presence, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
pres_env_cor <- cor(pres_env, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(pres_env_cor, "../output/env/pres_env_corr.csv", row.names = TRUE)
pres_corrplot <- corrplot(pres_env_cor , method = "color", type = "upper", order = "alphabet", tl.cex = 0.8)
dev.copy(png,"../output/env/simple_plots/pres_envcorr.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

to get some density plots all in one graphic, you need to change chunk output to in console, then go to the plot tab, make it fill the screen, then run then make bigger then save :( (probably a better way - this seems to be an issue with RStudio)
graphics.off()
tiff("../output/env/simple_plots/background_envcorr_density.tiff") # to automatically save the plot to a png AND show it inline
par(mfrow=c(4,4), mar=c(1,1,1,1))
for(i in 1:16){
plot(density(pres_env[,i], na.rm=T), main = names(pres_env)[i])
}
dev.off() # stops automatic saving of the plot to a png
null device
1
PUT THE CHUNK OUTPUT BACK TO INLINE
density plot with background and presence env. data
Inspired by Merrow 2013 - top paragraph of page 1063 (are the species observations uniformly distributed over the background, or are they skewed)
ggplot(pres_env, aes(x = temp_depth)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/temp_depth_backvspres.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(pres_env, aes(x = temp_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/temp_surface_backvspres.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(pres_env, aes(x = chl_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/chl_surface_backvspres.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(pres_env, aes(x = chl_depth)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/chl_depth_backvspres.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(pres_env, aes(x = salinity_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/salinity_surface_backvspres.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(pres_env, aes(x = salinity_depth)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/salinity_depth_backvspres.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(pres_env, aes(x = o2_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/o2_surface_backvspres.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(pres_env, aes(x = o2_depth)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/o2_depth_backvspres.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(pres_env, aes(x = mlp_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/mlp_backvspres.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(pres_env, aes(x = ssh_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/ssh_backvspres.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

NAFO Regions
compare the environmental correlates between different NAFO regions
first see which nafo zones were sampled in each year
nafo_by_yr
nafo_zone
year 0A 0B 1C 2G 2H 2J 3K 3L 3M 3N 3O 3Pn 3Ps 4R 4S 4T 4Vn 4Vs 4W 4X 5Y 5Ze HudsonStrait
1998 0 0 0 0 12 55 106 211 0 42 68 2 55 0 0 46 8 7 4 3 1 0 0
1999 0 0 0 0 0 34 93 196 0 40 47 2 54 0 0 76 9 34 27 2 2 0 0
2000 0 0 0 0 0 51 111 194 2 50 46 4 46 0 0 82 12 26 19 1 0 0 0
2001 0 0 0 0 3 34 109 200 0 48 53 2 55 0 0 49 6 28 10 0 0 0 0
2002 0 0 0 0 0 33 65 207 0 46 56 4 57 0 0 101 8 27 14 1 0 0 0
2003 0 0 0 0 0 46 60 214 0 60 72 3 79 0 0 40 8 20 15 1 0 0 0
2004 0 0 0 0 8 56 194 181 0 52 61 6 63 36 63 128 10 11 5 1 0 0 0
2005 0 7 0 7 0 46 86 187 0 37 49 1 40 41 86 113 19 20 21 4 7 0 0
2006 3 4 0 3 13 43 166 164 0 22 24 0 18 23 105 130 11 34 27 9 7 1 0
2007 0 10 0 3 0 32 79 156 0 51 54 1 59 25 100 150 9 19 11 0 0 0 26
2008 3 7 0 0 6 48 75 156 0 43 50 0 73 52 106 129 5 18 13 3 0 1 0
2009 0 0 0 1 0 45 92 164 0 49 62 8 59 13 43 101 6 1 22 0 3 0 9
2010 0 9 1 0 6 34 106 187 0 56 60 3 47 12 39 115 12 16 14 0 0 0 0
2011 0 9 0 1 5 35 75 147 0 64 45 10 57 23 43 101 6 6 2 0 0 0 12
2012 0 7 0 1 0 0 0 0 0 0 0 0 0 23 50 106 5 1 3 1 0 0 0
2013 0 3 0 6 1 0 0 2 0 0 0 0 0 21 44 88 15 2 4 0 0 0 8
2014 1 13 0 1 0 0 0 1 0 0 0 0 0 0 0 92 6 0 0 0 0 0 4
2015 0 8 0 1 0 0 0 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 3
and by month
nafo_by_mth <- with(presence, table(nafo_zone, month))
write.csv(nafo_by_mth, file = "../output/bio/nafozone_by_mth.csv")
nafo_by_mth
month
nafo_zone 1 2 3 4 5 6 7 8 9 10 11 12
0A 0 0 0 0 0 0 0 3 0 3 1 0
0B 0 0 0 0 0 0 0 53 20 4 0 0
1C 0 0 0 0 0 0 0 1 0 0 0 0
2G 0 0 0 0 0 0 16 8 0 0 0 0
2H 0 0 0 0 0 0 2 0 0 49 0 3
2J 6 0 0 0 0 0 0 0 0 119 363 104
3K 235 4 0 0 0 0 0 2 0 0 575 601
3L 2 0 0 0 98 1305 47 1 0 62 730 324
3M 0 0 0 0 0 0 0 0 0 2 0 0
3N 0 0 0 0 283 229 0 0 0 106 40 2
3O 0 0 0 28 480 28 1 0 5 182 22 1
3Pn 0 0 0 39 7 0 0 0 0 0 0 0
3Ps 0 0 0 615 147 0 0 0 0 0 1 0
4R 0 0 0 0 0 0 15 253 1 0 0 0
4S 0 0 0 0 2 1 4 670 2 0 0 0
4T 0 0 0 0 0 3 8 413 1216 7 0 0
4Vn 0 0 0 1 0 0 132 8 14 0 0 0
4Vs 0 0 169 2 0 0 96 3 0 0 0 0
4W 0 5 148 11 0 0 41 4 0 1 1 0
4X 0 0 3 0 0 0 20 0 0 2 1 0
5Y 0 0 0 1 8 3 3 0 0 2 3 0
5Ze 0 1 1 0 0 0 0 0 0 0 0 0
HudsonStrait 0 0 0 0 0 0 1 7 0 54 0 0
Interesting that there is a point in 1C - this is outside Canadian waters remove from the dataset
presab <- presab[!(presab$nafo_zone == "1C" & presab$occurrence == "1"), ]
write.csv(presab, "../output/bio/presab_10k.csv", row.names = FALSE)
presence <- presence[!(presence$nafo_zone == "1C"), ]
and by month again
nafo_by_mth <- with(presence, table(nafo_zone, month))
write.csv(nafo_by_mth, file = "../output/bio/nafozone_by_mth.csv")
nafo_by_mth
month
nafo_zone 1 2 3 4 5 6 7 8 9 10 11 12
0A 0 0 0 0 0 0 0 3 0 3 1 0
0B 0 0 0 0 0 0 0 53 20 4 0 0
1C 0 0 0 0 0 0 0 0 0 0 0 0
2G 0 0 0 0 0 0 16 8 0 0 0 0
2H 0 0 0 0 0 0 2 0 0 49 0 3
2J 6 0 0 0 0 0 0 0 0 119 363 104
3K 235 4 0 0 0 0 0 2 0 0 575 601
3L 2 0 0 0 98 1305 47 1 0 62 730 324
3M 0 0 0 0 0 0 0 0 0 2 0 0
3N 0 0 0 0 283 229 0 0 0 106 40 2
3O 0 0 0 28 480 28 1 0 5 182 22 1
3Pn 0 0 0 39 7 0 0 0 0 0 0 0
3Ps 0 0 0 615 147 0 0 0 0 0 1 0
4R 0 0 0 0 0 0 15 253 1 0 0 0
4S 0 0 0 0 2 1 4 670 2 0 0 0
4T 0 0 0 0 0 3 8 413 1216 7 0 0
4Vn 0 0 0 1 0 0 132 8 14 0 0 0
4Vs 0 0 169 2 0 0 96 3 0 0 0 0
4W 0 5 148 11 0 0 41 4 0 1 1 0
4X 0 0 3 0 0 0 20 0 0 2 1 0
5Y 0 0 0 1 8 3 3 0 0 2 3 0
5Ze 0 1 1 0 0 0 0 0 0 0 0 0
HudsonStrait 0 0 0 0 0 0 1 7 0 54 0 0
density plot with background and presence env. data by NAFO region
What I want to see if if there is a marked difference between the env. correlates of the presence points between NAFO regions. This is also to try deal with sampling bias (b/c the whole region is not uniformly sampled in each month, but rather nafo regions have a strong month bias)
first create NAFO-region datasets
nafo0a <- subset(presence, nafo_zone == "0A")
nafo0b <- subset(presence, nafo_zone == "0B")
nafo2g <- subset(presence, nafo_zone == "2G")
nafo2h <- subset(presence, nafo_zone == "2H")
nafo2j <- subset(presence, nafo_zone == "2J")
nafo3k <- subset(presence, nafo_zone == "3K")
nafo3l <- subset(presence, nafo_zone == "3L")
nafo3m <- subset(presence, nafo_zone == "3M")
nafo3n <- subset(presence, nafo_zone == "3N")
nafo3o <- subset(presence, nafo_zone == "3O")
nafo3ps <- subset(presence, nafo_zone == "3Ps")
nafo4r <- subset(presence, nafo_zone == "4R")
nafo4s <- subset(presence, nafo_zone == "4S")
nafo4t <- subset(presence, nafo_zone == "4T")
nafo4vn <- subset(presence, nafo_zone == "4Vn")
nafo4vs <- subset(presence, nafo_zone == "4Vs")
nafo4w <- subset(presence, nafo_zone == "4W")
nafo4x <- subset(presence, nafo_zone == "4X")
nafo5y <- subset(presence, nafo_zone == "5Y")
nafo5ze <- subset(presence, nafo_zone == "5ZE")
nafohudson <- subset(presence, nafo_zone == "HudsonStrait")
plot by each variable, less 3m (2 samples) and 5ze (2 samples)
ggplot(nafo0a, aes(x = temp_surface, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/temp_surface_nafo.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(nafo0a, aes(x = temp_depth, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/temp_depth_nafo.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(nafo0a, aes(x = chl_surface, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/chl_surface_nafo.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(nafo0a, aes(x = chl_depth, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/chl_depth_nafo.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(nafo0a, aes(x = salinity_surface, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/salinity_surface_nafo.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(nafo0a, aes(x = salinity_depth, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/salinity_depth_nafo.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(nafo0a, aes(x = o2_surface, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/o2_surface_nafo.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(nafo0a, aes(x = o2_depth, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/o2_depth_nafo.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(nafo0a, aes(x = mlp_surface, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/mlp_nafo.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(nafo0a, aes(x = ssh_surface, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/ssh_nafo.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

Let’s plot the variables by nafo region/year then by month
pr98 <- subset(presence, year == "1998")
boxplot(pr98$temp_depth ~ pr98$nafo_zone, xlab = "NAFO Region", ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth per NAFO Zone")
pr98 <- subset(presence, year == "1998")
pr11 <- subset(presence, year == "2011")
par(mfrow=c(2,1))
boxplot(pr98$temp_depth ~ pr98$nafo_zone, xlab = "NAFO Region", ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth per NAFO Zone")
boxplot(pr11$temp_depth ~ pr11$nafo_zone, xlab = "NAFO Region", ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth per NAFO Zone")
ok scrap the nafo region analysis - it is too mixed up with month (so seeing if region or month is a factor that needs to be factored in to the model is not appropriate)
remap who sampled
Now lets check the number of records and spatial-temporal distribution of the observations by institution code to make sure none are dodgy
first a table of how many observations each instituioncode has
obs_by_ins <- count(presence, "institutioncode")
obs_by_ins
write.csv(obs_by_ins, file = "../output/bio/samplinginstitutions/no_observations_institutioncode.csv")
ok so NEFSC and ROM only have one point each
Lets take a look at the spatial breakdown of these institutions.First all points…
map2 <- getMap(resolution = "low") #creates an object called map at low resoultion
plot(map2, xlim = c(-70, -43), ylim =c(38, 70), asp = 1, main = "All Occurrences", col = "cornsilk") #the x and y lim are the long-lat bounds of the map
points(presence$decimalLongitude, presence$decimalLatitude, col = "red") #this adds points to the mapet", xlab = "Longitude", ylab = "Latitude")
dev.copy(png, "../output/bio/samplinginstitutions/all_occurrences.png") #this prints a png of the plot
png
3
dev.off() #this turns off the print command
png
2

Note there is one point up by iceland that you should get rid of (Icelandic population thought to be seperate from Labrador, but it is unclear if this is true or not).
Map the institutioncode == ARC only data…

ROM_obs <- presence[presence$institutioncode == "ROM", ]
map2 <- getMap(resolution = "low") #creates an object called map at low resoultion
plot(map2, xlim = c(-70, -43), ylim =c(39, 70), asp = 1, main = "Royal Ontario Museum Occurrences", col = "cornsilk") #the x and y lim are the long-lat bounds of the map
points(ROM_obs$decimalLongitude, ROM_obs$decimalLatitude, col = "red") #this adds points to the mapet", xlab = "Longitude", ylab = "Latitude")
dev.copy(png, "../output/bio/samplinginstitutions/ROM_occurrences_all.png") #this prints a png of the plot
png
3
check for gear type
what are the unique gear types you have in your presence data, and how many?
gear_count <- count(presence, "gear")
write.csv(gear_count, file = "../output/bio/gear_count.csv")
gear_count
so the vast majority are trawls of some type.
map the gear usage in Arcgis (gear_type_map)
create a table of gear use by month
gearby_mth <- with(presence, table(gear, month))
write.csv(gearby_mth, file = "../output/bio/gear_by_mth.csv")
gearby_mth
month
gear 1 2 3 4 5 6 7 8 9 10 11 12
bottom_trawl 0 6 318 12 8 3 286 14 0 2 3 0
bottom_trawl_alfredo_03 0 0 0 0 0 0 0 0 0 3 0 0
bottom_trawl_campelen_14 0 0 0 0 0 0 18 33 0 0 0 0
bottom_trawl_campelen_1800 243 4 0 682 1015 1562 56 841 10 520 1722 1034
bottom_trawl_campelen_21 0 0 0 0 0 0 1 35 20 0 0 0
bottom_trawl_cosmos_2600 0 0 0 0 0 0 0 3 0 58 1 0
bottom_trawl_western_IIA 0 0 0 0 0 0 0 6 1209 5 0 0
unknown 0 0 1 0 2 4 22 492 16 2 8 0
vertical_plankton_tow 0 0 2 3 0 0 3 1 3 3 3 1
What I want to see if if there is a marked difference between the env. correlates of the presence points between gear type used. This is also to try deal with detection bias between gear type (b/c the whole region is not uniformly sampled by the same gear type)
first create gear datasets
presence$gear <- as.character(presence$gear)
bottom_trawl <- subset(presence, gear == "bottom_trawl")
bottom_trawl_alfredo_03 <- subset(presence, gear == "bottom_trawl_alfredo_03")
bottom_trawl_campelen_14 <- subset(presence, gear == "bottom_trawl_campelen_14")
bottom_trawl_campelen_1800 <- subset(presence, gear == "bottom_trawl_campelen_1800")
bottom_trawl_campelen_21 <- subset(presence, gear == "bottom_trawl_campelen_21")
bottom_trawl_cosmos_2600 <- subset(presence, gear == "bottom_trawl_cosmos_2600")
bottom_trawl_western_IIA <- subset(presence, gear == "bottom_trawl_western_IIA")
unknown <- subset(presence, gear == "unknown")
vertical_plankton_tow <- subset(presence, gear == "vertical_plankton_tow")
plot by each variable, less 3m (2 samples) 1c (one sample) and 5ze (zero samples?!)
ggplot(bottom_trawl, aes(x = temp_surface, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/temp_surface_gear.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(bottom_trawl, aes(x = temp_depth, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/temp_depth_gear.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(bottom_trawl, aes(x = chl_surface, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/chl_surface_gear.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(bottom_trawl, aes(x = chl_depth, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/chl_depth_gear.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(bottom_trawl, aes(x = salinity_surface, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/salinity_surface_gear.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(bottom_trawl, aes(x = salinity_depth, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/salinity_depth_gear.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(bottom_trawl, aes(x = o2_surface, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/o2_surface_gear.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(bottom_trawl, aes(x = o2_depth, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/o2_depth_gear.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(bottom_trawl, aes(x = mlp_surface, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/mlp_gear.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

ggplot(bottom_trawl, aes(x = ssh_surface, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/ssh_gear.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

par(mar=c(7,5,1,1))
boxplot(presence$temp_depth ~ presence$gear, ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth by gear type", las = 2)
dev.copy(png, "../output/env/simple_plots/temperature_boxplot_dept_gear.png") # to automatically save the plot to a png AND show it inline
png
3
dev.off() # stops automatic saving of the plot to a png
png
2

what about a kruskal wallace test?
kruskal.test(presence$temp_depth ~ presence$gear)
Ok so there is a statistically sig difference somewhere in the temp at depth reported by the gear type (Kruskal-Wallis chi-squared = 248.27, df = 7, p-value < 2.2e-16)
To see where the difference(s) are run a Dunn test Zar (2010) states that the Dunn test (in the FSA package) is appropriate for groups with unequal numbers of observations.(Zar, J.H. 2010. Biostatistical Analysis, 5th ed. Pearson Prentice Hall: Upper Saddle River, NJ.) http://rcompanion.org/rcompanion/d_06.html
SAM WHEN DUNN IS INSTALLED, GO TO RCOMPANIONS.ORG AND LOOK FOR DUNN - CHECK CHROME HISTORY (PROBABLY UNDER KRUSKAL WALLIS) ALSO MAP THE DISTRIBUTION OF THESE GEAR TYPES
pairwise.wilcox.test(presence$temp_depth, presence$gear, p.adj='bonferroni', exact=F)
dunn test
gear_temp_depthdunn <- dunnTest(presence$temp_depth, presence$gear, list = TRUE)
gear_temp_depthdunn
write.csv(table, "../output/env/gear_temp_depthdunn.csv", row.names = TRUE)
vif
for this you need the joined dataset.
vif_allpresab <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allpresab, "../output/bio/vif/vif_allpresab.csv", row.names = TRUE)
vif_allpresab
GVIF Df GVIF^(1/(2*Df))
temp_surface 29.568344 1 5.437678
temp_depth 2.179621 1 1.476354
salinity_surface 8.203658 1 2.864203
salinity_depth 5.680020 1 2.383279
o2_surface 28.595188 1 5.347447
o2_depth 5.294821 1 2.301048
chl_surface 3.524117 1 1.877263
chl_depth 2.558851 1 1.599641
bottom_depth 2.704882 1 1.644653
mlp_surface 1.972801 1 1.404564
ssh_surface 4.470089 1 2.114259
gear 11.472422 8 1.164739
nao_sample 1.151909 1 1.073270
nao_prev 1.130309 1 1.063160
nao_winter 1.093324 1 1.045621
amo_sample 4.954083 1 2.225777
amo_prev 5.084722 1 2.254933
amo_winter 1.129430 1 1.062747
interpret - see https://stats.stackexchange.com/questions/70679/which-variance-inflation-factor-should-i-be-using-textgvif-or-textgvif/96584#96584 To make GVIFs comparable across dimensions, we suggested using GVIF^(1/(2Df)), where Df is the number of coefficients in the subset (ref fox and motette 1992 in zotero) or the 2 continuous variables, GVIFˆ(1/(2Df)) (which is basically the square root of the VIF/GVIF value as DF=1) is the proportional change of the standard error and confidence interval of their coefficients due to the level of collinearity. The GVIFˆ(1/(2Df)) value of the categorical variable is a similar measure for the reduction in precision of the coefficients’ estimation due to collinearity. apparently i just need to square GVIF^(1/(2Df)) and then use the normal VIF “rule of thumb”…
vif_allpresab_sq <- read.csv("../output/bio/vif/vif_allpresab.csv", header = TRUE)
vif_allpresab_sq$GVIF2Dfsq <- vif_allpresab_sq$GVIF..1..2.Df..^2
write.csv(vif_allpresab_sq, "../output/bio/vif/vif_allpresab.csv", row.names = TRUE)
vif_allpresab_sq
As per SLR suggestion, rerun without gear
vif_allbutgear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutgear, "../output/bio/vif/vif_allbutgear.csv", row.names = TRUE)
vif_allbutgear
temp_surface temp_depth salinity_surface salinity_depth o2_surface o2_depth chl_surface chl_depth bottom_depth mlp_surface
11.465759 3.295722 4.826882 5.206847 12.958031 4.175056 2.306772 2.101983 2.857971 1.228628
ssh_surface nao_sample nao_prev nao_winter amo_sample amo_prev amo_winter
4.478627 1.094630 1.096453 1.102418 4.780916 4.851814 1.059102
xx As per SLR suggestion, rerun without gear and most highly correlated variables
vif_allbutgearhighlycorr <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + mlp_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbutgearhighlycorr, "../output/bio/vif/vif_allbutgearhighlycorr.csv", row.names = TRUE)
vif_allbutgearhighlycorr
temp_surface temp_depth salinity_surface salinity_depth o2_depth chl_surface mlp_surface nao_sample nao_prev nao_winter
2.920465 3.203729 4.186400 4.860349 3.065348 1.325612 1.112185 1.078420 1.079194 1.070659
amo_sample amo_winter
1.253479 1.057472
As per SLR suggestion, rerun with gear but without most highly correlated variables
vif_allbuthighlycorr <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + mlp_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter + gear, data = presab))
write.csv(vif_allbuthighlycorr, "../output/bio/vif/vif_allbuthighlycorr.csv", row.names = TRUE)
vif_allbuthighlycorr
GVIF Df GVIF^(1/(2*Df))
temp_surface 4.687780 1 2.165128
temp_depth 1.649841 1 1.284461
salinity_surface 6.480747 1 2.545731
salinity_depth 3.204241 1 1.790039
o2_depth 3.872181 1 1.967786
chl_surface 2.167748 1 1.472327
mlp_surface 1.781169 1 1.334605
nao_sample 1.126875 1 1.061544
nao_prev 1.102211 1 1.049862
nao_winter 1.055682 1 1.027464
amo_sample 1.332280 1 1.154244
amo_winter 1.104007 1 1.050718
gear 9.362047 8 1.150034
vif_allbuthighlycorr_sq <- read.csv("../output/bio/vif/vif_allbuthighlycorr.csv", header = TRUE)
vif_allbuthighlycorr_sq$GVIF2Dfsq <- vif_allbuthighlycorr_sq$GVIF..1..2.Df..^2
write.csv(vif_allbuthighlycorr_sq, "../output/bio/vif/vif_allbuthighlycorr.csv", row.names = TRUE)
vif_allbuthighlycorr_sq
ok remove one variable at a time - leave gear in
remove bottom_depth
vif_allbutbot_prev <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutbot_prev, "../output/bio/vif/vif_allbutbot_prev.csv", row.names = TRUE)
vif_allbutbot_prev <- read.csv("../output/bio/vif/vif_allbutbot_prev.csv", header = TRUE)
vif_allbutbot_prev$GVIF2Dfsq <- vif_allbutbot_prev$GVIF..1..2.Df..^2
write.csv(vif_allbutbot_prev, "../output/bio/vif/vif_allbutbot_prev.csv", row.names = TRUE)
vif_allbutbot_prev
and leave gear out
remove bottom_depth + gear
vif_allbutbot_prevgear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutbot_prevgear, "../output/bio/vif/vif_allbutbot_prevgear.csv", row.names = TRUE)
vif_allbutbot_prevgear
temp_surface temp_depth salinity_surface salinity_depth o2_surface o2_depth chl_surface chl_depth mlp_surface ssh_surface
11.354053 3.237083 4.825633 5.181528 12.945442 4.148216 2.291018 2.098356 1.228423 3.021062
nao_sample nao_prev nao_winter amo_sample amo_prev amo_winter
1.093545 1.096446 1.102206 4.776866 4.851800 1.058909
remove amo_prev
vif_allbutamo_prev <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbutamo_prev, "../output/bio/vif/vif_allbutamo_prev.csv", row.names = TRUE)
vif_allbutamo_prev <- read.csv("../output/bio/vif/vif_allbutamo_prev.csv", header = TRUE)
vif_allbutamo_prev$GVIF2Dfsq <- vif_allbutamo_prev$GVIF..1..2.Df..^2
write.csv(vif_allbutamo_prev, "../output/bio/vif/vif_allbutamo_prev.csv", row.names = TRUE)
vif_allbutamo_prev
and leave gear out
remove amo_prev + gear
vif_allbutamo_prevgear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbutamo_prevgear, "../output/bio/vif/vif_allbutamo_prevgear.csv", row.names = TRUE)
vif_allbutamo_prevgear
temp_surface temp_depth salinity_surface salinity_depth o2_surface o2_depth chl_surface chl_depth bottom_depth mlp_surface
11.347391 3.295716 4.826881 5.206384 12.765958 4.174880 2.304471 2.100476 2.857962 1.224003
ssh_surface nao_sample nao_prev nao_winter amo_sample amo_winter
4.466039 1.080058 1.079727 1.073580 1.265428 1.058916
remove chl_depth
vif_allbutchl_depth <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutchl_depth, "../output/bio/vif/vif_allbutchl_depth.csv", row.names = TRUE)
vif_allbutchl_depth <- read.csv("../output/bio/vif/vif_allbutchl_depth.csv", header = TRUE)
vif_allbutchl_depth$GVIF2Dfsq <- vif_allbutchl_depth$GVIF..1..2.Df..^2
write.csv(vif_allbutchl_depth, "../output/bio/vif/vif_allbutchl_depth.csv", row.names = TRUE)
vif_allbutchl_depth
remove chl_depth and gear
vif_allbutchl_depthgear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutchl_depthgear, "../output/bio/vif/vif_allbutchl_depthgear.csv", row.names = TRUE)
vif_allbutchl_depthgear
temp_surface temp_depth salinity_surface salinity_depth o2_surface o2_depth chl_surface bottom_depth mlp_surface ssh_surface
11.465368 3.286337 4.763276 5.202900 12.629715 3.253857 1.763718 2.853040 1.227709 4.463921
nao_sample nao_prev nao_winter amo_sample amo_prev amo_winter
1.094594 1.096371 1.102390 4.780796 4.848337 1.059043
remove ssh_surface
vif_allbutssh_surface <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutssh_surface, "../output/bio/vif/vif_allbutssh_surface.csv", row.names = TRUE)
vif_allbutssh_surface <- read.csv("../output/bio/vif/vif_allbutssh_surface.csv", header = TRUE)
vif_allbutssh_surface$GVIF2Dfsq <- vif_allbutssh_surface$GVIF..1..2.Df..^2
write.csv(vif_allbutssh_surface, "../output/bio/vif/vif_allbutssh_surface.csv", row.names = TRUE)
vif_allbutssh_surface
remove ssh_surface & gear
vif_allbutssh_surfacegear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutssh_surfacegear, "../output/bio/vif/vif_allbutssh_surfacegear.csv", row.names = TRUE)
vif_allbutssh_surfacegear
temp_surface temp_depth salinity_surface salinity_depth o2_surface o2_depth chl_surface chl_depth bottom_depth mlp_surface
10.046950 3.293527 4.585939 5.072030 11.450006 4.054837 2.113070 2.095081 1.927847 1.182305
nao_sample nao_prev nao_winter amo_sample amo_prev amo_winter
1.093310 1.096432 1.100775 4.746652 4.838178 1.058444
remove o2_surface
vif_allbuto2_surface <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuto2_surface, "../output/bio/vif/vif_allbuto2_surface.csv", row.names = TRUE)
vif_allbuto2_surface <- read.csv("../output/bio/vif/vif_allbuto2_surface.csv", header = TRUE)
vif_allbuto2_surface$GVIF2Dfsq <- vif_allbuto2_surface$GVIF..1..2.Df..^2
write.csv(vif_allbuto2_surface, "../output/bio/vif/vif_allbuto2_surface.csv", row.names = TRUE)
vif_allbuto2_surface
remove o2_surface & gear
vif_allbuto2_surfacegear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuto2_surfacegear, "../output/bio/vif/vif_allbuto2_surfacegear.csv", row.names = TRUE)
vif_allbuto2_surfacegear
temp_surface temp_depth salinity_surface salinity_depth o2_depth chl_surface chl_depth bottom_depth mlp_surface ssh_surface
3.230352 3.293953 4.763841 5.155372 3.880777 1.788680 2.048725 2.855194 1.224247 3.957415
nao_sample nao_prev nao_winter amo_sample amo_prev amo_winter
1.094604 1.096448 1.102310 4.720633 4.779897 1.058061
as per SLR chat jan 23:
remove salinity_surface only
vif_allbutsalinitysurface <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutsalinitysurface, "../output/bio/vif/vif_allbutsalinitysurface.csv", row.names = TRUE)
vif_allbutsalinitysurface <- read.csv("../output/bio/vif/vif_allbutsalinitysurface.csv", header = TRUE)
vif_allbutsalinitysurface$GVIF2Dfsq <- vif_allbutsalinitysurface$GVIF..1..2.Df..^2
write.csv(vif_allbutsalinitysurface, "../output/bio/vif/vif_allbutsalinitysurface.csv", row.names = TRUE)
vif_allbutsalinitysurface
and without gear
vif_allbutsalinitysurfacegear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutsalinitysurfacegear, "../output/bio/vif/vif_allbutsalinitysurfacegear.csv", row.names = TRUE)
vif_allbutsalinitysurfacegear
temp_surface temp_depth salinity_depth o2_surface o2_depth chl_surface chl_depth bottom_depth mlp_surface ssh_surface nao_sample nao_prev
11.063264 2.549610 2.633799 12.788795 2.814414 2.301361 2.074284 2.857231 1.227348 4.255068 1.094397 1.096250
nao_winter amo_sample amo_prev amo_winter
1.102205 4.766710 4.851814 1.059071
remove temp_surface only
vif_allbuttempsurface <- vif(lm(occurrence ~ temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuttempsurface, "../output/bio/vif/vif_allbuttempsurface.csv", row.names = TRUE)
vif_allbuttempsurface <- read.csv("../output/bio/vif/vif_allbuttempsurface.csv", header = TRUE)
vif_allbuttempsurface$GVIF2Dfsq <- vif_allbuttempsurface$GVIF..1..2.Df..^2
write.csv(vif_allbuttempsurface, "../output/bio/vif/vif_allbuttempsurface.csv", row.names = TRUE)
vif_allbuttempsurface
vif_allbuttempsurfacegear <- vif(lm(occurrence ~ temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuttempsurfacegear, "../output/bio/vif/vif_allbuttempsurfacegear.csv", row.names = TRUE)
vif_allbuttempsurfacegear
temp_depth salinity_surface salinity_depth o2_surface o2_depth chl_surface chl_depth bottom_depth mlp_surface ssh_surface
3.072096 4.657438 5.058933 3.650783 4.062894 2.195182 2.101911 2.830127 1.215545 3.924427
nao_sample nao_prev nao_winter amo_sample amo_prev amo_winter
1.092118 1.096043 1.101830 4.646480 4.801726 1.057256
now remove temp_surface plus highly correlated
#with gear
vif_allbuthighcorrtempsurface <- vif(lm(occurrence ~ temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + mlp_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbuthighcorrtempsurface, "../output/bio/vif/vif_allbuthighcorrtempsurface.csv", row.names = TRUE)
vif_allbuthighcorrtempsurface <- read.csv("../output/bio/vif/vif_allbuthighcorrtempsurface.csv", header = TRUE)
vif_allbuthighcorrtempsurface$GVIF2Dfsq <- vif_allbuthighcorrtempsurface$GVIF..1..2.Df..^2
write.csv(vif_allbuthighcorrtempsurface, "../output/bio/vif/vif_allbuthighcorrtempsurface.csv", row.names = TRUE)
vif_allbuthighcorrtempsurface
#without gear
vif_allbuthighcorrtempsurfacegear <- vif(lm(occurrence ~ temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + mlp_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbuthighcorrtempsurfacegear, "../output/bio/vif/vif_allbuthighcorrtempsurfacegear.csv", row.names = TRUE)
vif_allbuthighcorrtempsurfacegear
temp_depth salinity_surface salinity_depth o2_depth chl_surface mlp_surface nao_sample nao_prev nao_winter amo_sample
2.063406 3.936504 4.736628 3.064882 1.172481 1.098150 1.071556 1.077449 1.069530 1.169899
amo_winter
1.056621
now remove temp_surface plus salinity_surface
#with gear
vif_allbuttempsalsurface <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuttempsalsurface, "../output/bio/vif/vif_allbuttempsalsurface.csv", row.names = TRUE)
vif_allbuttempsalsurface <- read.csv("../output/bio/vif/vif_allbuttempsalsurface.csv", header = TRUE)
vif_allbuttempsalsurface$GVIF2Dfsq <- vif_allbuttempsalsurface$GVIF..1..2.Df..^2
write.csv(vif_allbuttempsalsurface, "../output/bio/vif/vif_allbuttempsalsurface.csv", row.names = TRUE)
vif_allbuttempsalsurface
#without gear
vif_allbuttempsalsurfacegear <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuttempsalsurfacegear, "../output/bio/vif/vif_allbuttempsalsurfacegear.csv", row.names = TRUE)
vif_allbuttempsalsurfacegear
temp_depth salinity_depth o2_surface o2_depth chl_surface chl_depth bottom_depth mlp_surface ssh_surface nao_sample nao_prev nao_winter
2.449336 2.626476 3.624181 2.800383 2.175973 2.072655 2.826585 1.215331 3.535876 1.091487 1.095706 1.101725
amo_sample amo_prev amo_winter
4.609894 4.799836 1.057063
now remove temp_surface plus salinity_surface + highly correlated
#with gear
vif_allbuthighcorrtempsalsurface <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + mlp_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbuthighcorrtempsalsurface, "../output/bio/vif/vif_allbuthighcorrtempsalsurface.csv", row.names = TRUE)
vif_allbuthighcorrtempsalsurface <- read.csv("../output/bio/vif/vif_allbuthighcorrtempsalsurface.csv", header = TRUE)
vif_allbuthighcorrtempsalsurface$GVIF2Dfsq <- vif_allbuthighcorrtempsalsurface$GVIF..1..2.Df..^2
write.csv(vif_allbuthighcorrtempsalsurface, "../output/bio/vif/vif_allbuthighcorrtempsalsurface.csv", row.names = TRUE)
vif_allbuthighcorrtempsalsurface
#without gear
vif_allbuthighcorrtempsalsurfacegear <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + mlp_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbuthighcorrtempsalsurfacegear, "../output/bio/vif/vif_allbuthighcorrtempsalsurfacegear.csv", row.names = TRUE)
vif_allbuthighcorrtempsalsurfacegear
temp_depth salinity_depth o2_depth chl_surface mlp_surface nao_sample nao_prev nao_winter amo_sample amo_winter
1.536582 1.314145 1.670188 1.167592 1.085566 1.070786 1.076759 1.069452 1.138991 1.056420
Just out of curiosity, a vif will all but but atmos drivers
vif_allbutnaoamo <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear, data = presab))
write.csv(vif_allbutnaoamo, "../output/bio/vif/vif_allbutnaoamo.csv", row.names = TRUE)
vif_allbutnaoamo <- read.csv("../output/bio/vif/vif_allbutnaoamo.csv", header = TRUE)
vif_allbutnaoamo$GVIF2Dfsq <- vif_allbutnaoamo$GVIF..1..2.Df..^2
write.csv(vif_allbutnaoamo, "../output/bio/vif/vif_allbutnaoamo.csv", row.names = TRUE)
vif_allbutnaoamo
not much diff..
monthly spearmans correlations and VIF
curious - does correlations/vif alter between months?
First split the dataset into monthly
presab$gear <- as.character(presab$gear)
janpresab <- subset(presab, month == "1")
febpresab <- subset(presab, month == "2")
marpresab <- subset(presab, month == "3")
aprpresab <- subset(presab, month == "4")
maypresab <- subset(presab, month == "5")
junpresab <- subset(presab, month == "6")
julpresab <- subset(presab, month == "7")
augpresab <- subset(presab, month == "8")
seppresab <- subset(presab, month == "9")
octpresab <- subset(presab, month == "10")
novpresab <- subset(presab, month == "11")
decpresab <- subset(presab, month == "12")
now get the background points for each month (for spearmans)
janback <- subset(janpresab, occurrence == "0")
febback <- subset(febpresab, occurrence == "0")
marback <- subset(marpresab, occurrence == "0")
aprback <- subset(aprpresab, occurrence == "0")
mayback <- subset(maypresab, occurrence == "0")
junback <- subset(junpresab, occurrence == "0")
julback <- subset(julpresab, occurrence == "0")
augback <- subset(augpresab, occurrence == "0")
sepback <- subset(seppresab, occurrence == "0")
octback <- subset(octpresab, occurrence == "0")
novback <- subset(novpresab, occurrence == "0")
decback <- subset(decpresab, occurrence == "0")
run the correlations on each month’s background points
janback <- subset(janback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
janback_cor <- cor(janback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(janback_cor, "../output/env/janback_cor.csv", row.names = TRUE)
febback <- subset(febback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
febback_cor <- cor(febback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(febback_cor, "../output/env/febback_cor.csv", row.names = TRUE)
marback <- subset(marback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
marback_cor <- cor(marback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(marback_cor, "../output/env/marback_cor.csv", row.names = TRUE)
aprback <- subset(aprback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
aprback_cor <- cor(aprback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(aprback_cor, "../output/env/aprback_cor.csv", row.names = TRUE)
mayback <- subset(mayback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
mayback_cor <- cor(mayback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(mayback_cor, "../output/env/mayback_cor.csv", row.names = TRUE)
junback <- subset(junback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
junback_cor <- cor(junback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(junback_cor, "../output/env/junback_cor.csv", row.names = TRUE)
julback <- subset(julback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
julback_cor <- cor(julback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(julback_cor, "../output/env/julback_cor.csv", row.names = TRUE)
augback <- subset(augback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
augback_cor <- cor(augback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(augback_cor, "../output/env/augback_cor.csv", row.names = TRUE)
sepback <- subset(sepback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
sepback_cor <- cor(sepback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(sepback_cor, "../output/env/sepback_cor.csv", row.names = TRUE)
octback <- subset(octback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
octback_cor <- cor(octback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(octback_cor, "../output/env/octback_cor.csv", row.names = TRUE)
novback <- subset(novback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
novback_cor <- cor(novback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(novback_cor, "../output/env/novback_cor.csv", row.names = TRUE)
decback <- subset(decback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
decback_cor <- cor(decback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(decback_cor, "../output/env/decback_cor.csv", row.names = TRUE)
Run a VIF for each month (with and without gear)
vif_nogear_jan <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = janpresab))
Error in vif.default(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + :
there are aliased coefficients in the model
spearmans indicates chl_depth, mlp_surface, ssh_surface, temp_surface, o2_surface, salinity_surface, and bottom_depth, amo_prev (and for Jun and Oct chl_surface; and for jan amo_winter, ampo_prev, amo_sample, and NAO_prev, and feb amo_winter, ampo_prev, amo_sample, nao winter, and NAO_prev) all correlated every month. remove from each model and rerun Run a VIF for each month (with and without gear)
#with gear - for jan there is none because there is only one category of gear
#without gear
vif_nogear_cor_jan <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface+ nao_sample + nao_winter, data = janpresab))
write.csv(vif_nogear_cor_jan, "../output/bio/vif/monthly_vifs/vif_nogear_cor_jan.csv", row.names = TRUE)
vif_nogear_cor_jan
temp_depth salinity_depth o2_depth chl_surface nao_sample nao_winter
2.168252 2.551701 2.459972 1.742686 1.324866 1.316335
#without gear
vif_nogear_cor_feb <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample, data = febpresab))
write.csv(vif_nogear_cor_feb, "../output/bio/vif/monthly_vifs/vif_nogear_cor_feb.csv", row.names = TRUE)
vif_nogear_cor_feb
temp_depth salinity_depth o2_depth chl_surface nao_sample
2.636138 2.224945 2.376624 1.565463 1.007649
#with gear
vif_gear_cor_mar <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = marpresab))
write.csv(vif_gear_cor_mar, "../output/bio/vif/monthly_vifs/vif_gear_cor_mar.csv", row.names = TRUE)
vif_gear_cor_mar <- read.csv("../output/bio/vif/monthly_vifs/vif_gear_cor_mar.csv", header = TRUE)
vif_gear_cor_mar$GVIF2Dfsq <- vif_gear_cor_mar$GVIF..1..2.Df..^2
write.csv(vif_gear_cor_mar, "../output/bio/vif/monthly_vifs/vif_gear_cor_mar.csv", row.names = TRUE)
vif_gear_cor_mar
#without gear
vif_nogear_cor_mar <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = marpresab))
write.csv(vif_nogear_cor_mar, "../output/bio/vif/monthly_vifs/vif_nogear_cor_mar.csv", row.names = TRUE)
vif_nogear_cor_mar
temp_depth salinity_depth o2_depth chl_surface nao_sample nao_prev nao_winter amo_sample amo_winter
2.255506 1.977242 2.266471 1.296972 1.440578 1.429102 1.516391 1.436118 1.087738
#with gear
vif_gear_cor_apr <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = aprpresab))
write.csv(vif_gear_cor_apr, "../output/bio/vif/monthly_vifs/vif_gear_cor_apr.csv", row.names = TRUE)
vif_gear_cor_apr <- read.csv("../output/bio/vif/monthly_vifs/vif_gear_cor_apr.csv", header = TRUE)
vif_gear_cor_apr$GVIF2Dfsq <- vif_gear_cor_apr$GVIF..1..2.Df..^2
write.csv(vif_gear_cor_apr, "../output/bio/vif/monthly_vifs/vif_gear_cor_apr.csv", row.names = TRUE)
vif_gear_cor_apr
#without gear
vif_nogear_cor_apr <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = aprpresab))
write.csv(vif_nogear_cor_apr, "../output/bio/vif/monthly_vifs/vif_nogear_cor_apr.csv", row.names = TRUE)
vif_nogear_cor_apr
temp_depth salinity_depth o2_depth chl_surface nao_sample nao_prev nao_winter amo_sample amo_winter
1.859268 1.555059 2.085310 1.094040 3.303144 1.692901 4.099749 2.271605 1.239617
#with gear
vif_gear_cor_may <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = maypresab))
write.csv(vif_gear_cor_may, "../output/bio/vif/monthly_vifs/vif_gear_cor_may.csv", row.names = TRUE)
#without gear
vif_nogear_cor_may <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = maypresab))
write.csv(vif_nogear_cor_may, "../output/bio/vif/monthly_vifs/vif_nogear_cor_may.csv", row.names = TRUE)
vif_nogear_cor_may
temp_depth salinity_depth o2_depth chl_surface nao_sample nao_prev nao_winter amo_sample amo_winter
1.736955 1.380981 1.792550 1.379057 1.673749 4.310307 3.694028 2.508993 1.155045
#with gear
vif_gear_cor_jun <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = junpresab))
write.csv(vif_gear_cor_jun, "../output/bio/vif/monthly_vifs/vif_gear_cor_jun.csv", row.names = TRUE)
vif_gear_cor_jun
temp_depth salinity_depth o2_depth chl_surface gear nao_sample nao_prev nao_winter amo_sample amo_winter
2.528495 3.801194 1.894963 2.489998 1.086078 1.212537 1.414383 1.107102 1.771964 1.113434
#without gear
vif_nogear_cor_jun <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = junpresab))
write.csv(vif_nogear_cor_jun, "../output/bio/vif/monthly_vifs/vif_nogear_cor_jun.csv", row.names = TRUE)
vif_nogear_cor_jun
temp_depth salinity_depth o2_depth chl_surface nao_sample nao_prev nao_winter amo_sample amo_winter
1.542758 1.301562 1.638559 1.457845 1.181152 1.388201 1.058340 1.531045 1.055746
#with gear
vif_gear_cor_jul <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = julpresab))
essentially perfect fit: summary may be unreliable
write.csv(vif_gear_cor_jul, "../output/bio/vif/monthly_vifs/vif_gear_cor_jul.csv", row.names = TRUE)
vif_gear_cor_jul <- read.csv("../output/bio/vif/monthly_vifs/vif_gear_cor_jul.csv", header = TRUE)
vif_gear_cor_jul$GVIF2Dfsq <- vif_gear_cor_jul$GVIF..1..2.Df..^2
write.csv(vif_gear_cor_jul, "../output/bio/vif/monthly_vifs/vif_gear_cor_jul.csv", row.names = TRUE)
vif_gear_cor_jul
#without gear
vif_nogear_cor_jul <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = julpresab))
write.csv(vif_nogear_cor_jul, "../output/bio/vif/monthly_vifs/vif_nogear_cor_jul.csv", row.names = TRUE)
vif_nogear_cor_jul
temp_depth salinity_depth o2_depth chl_surface nao_sample nao_prev nao_winter amo_sample amo_winter
1.543069 1.325558 1.521027 1.206177 2.928616 2.496408 1.641297 1.298534 1.604576
#with gear
vif_gear_cor_aug <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = augpresab))
write.csv(vif_gear_cor_aug, "../output/bio/vif/monthly_vifs/vif_gear_cor_aug.csv", row.names = TRUE)
vif_gear_cor_aug <- read.csv("../output/bio/vif/monthly_vifs/vif_gear_cor_aug.csv", header = TRUE)
vif_gear_cor_aug$GVIF2Dfsq <- vif_gear_cor_aug$GVIF..1..2.Df..^2
write.csv(vif_gear_cor_aug, "../output/bio/vif/monthly_vifs/vif_gear_cor_aug.csv", row.names = TRUE)
vif_gear_cor_aug
#without gear
vif_nogear_cor_aug <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = augpresab))
write.csv(vif_nogear_cor_aug, "../output/bio/vif/monthly_vifs/vif_nogear_cor_aug.csv", row.names = TRUE)
vif_nogear_cor_aug
temp_depth salinity_depth o2_depth chl_surface nao_sample nao_prev nao_winter amo_sample amo_winter
1.536373 1.318218 1.315348 1.138970 1.382785 1.708867 1.341438 1.657683 1.158012
#with gear
vif_gear_cor_sep <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = seppresab))
write.csv(vif_gear_cor_sep, "../output/bio/vif/monthly_vifs/vif_gear_cor_sep.csv", row.names = TRUE)
vif_gear_cor_sep <- read.csv("../output/bio/vif/monthly_vifs/vif_gear_cor_sep.csv", header = TRUE)
vif_gear_cor_sep$GVIF2Dfsq <- vif_gear_cor_sep$GVIF..1..2.Df..^2
write.csv(vif_gear_cor_sep, "../output/bio/vif/monthly_vifs/vif_gear_cor_sep.csv", row.names = TRUE)
vif_gear_cor_sep
#without gear
vif_nogear_cor_sep <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = seppresab))
write.csv(vif_nogear_cor_sep, "../output/bio/vif/monthly_vifs/vif_nogear_cor_sep.csv", row.names = TRUE)
vif_nogear_cor_sep
temp_depth salinity_depth o2_depth chl_surface nao_sample nao_prev nao_winter amo_sample amo_winter
1.428756 1.194681 1.224031 1.210142 2.019480 1.745438 1.639778 1.203383 1.733592
#with gear
vif_gear_cor_oct <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = octpresab))
write.csv(vif_gear_cor_oct, "../output/bio/vif/monthly_vifs/vif_gear_cor_oct.csv", row.names = TRUE)
vif_gear_cor_oct
GVIF Df GVIF^(1/(2*Df))
temp_depth 3.320049 1 1.822100
salinity_depth 3.853326 1 1.962989
o2_depth 4.823800 1 2.196315
chl_surface 3.027180 1 1.739879
gear 5.115930 5 1.177314
nao_sample 1.464780 1 1.210281
nao_prev 4.402273 1 2.098160
nao_winter 1.444378 1 1.201823
amo_sample 2.191129 1 1.480246
amo_winter 2.923263 1 1.709755
vif_gear_cor_oct <- read.csv("../output/bio/vif/monthly_vifs/vif_gear_cor_oct.csv", header = TRUE)
vif_gear_cor_oct$GVIF2Dfsq <- vif_gear_cor_oct$GVIF..1..2.Df..^2
write.csv(vif_gear_cor_oct, "../output/bio/vif/monthly_vifs/vif_gear_cor_oct.csv", row.names = TRUE)
vif_gear_cor_oct
#without gear
vif_nogear_cor_oct <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = octpresab))
write.csv(vif_nogear_cor_oct, "../output/bio/vif/monthly_vifs/vif_nogear_cor_oct.csv", row.names = TRUE)
vif_nogear_cor_oct
temp_depth salinity_depth o2_depth chl_surface nao_sample nao_prev nao_winter amo_sample amo_winter
1.674621 1.320634 1.429731 1.421107 1.374528 3.414508 1.220549 2.089117 2.206526
#with gear
vif_gear_cor_nov <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = novpresab))
essentially perfect fit: summary may be unreliable
write.csv(vif_gear_cor_nov, "../output/bio/vif/monthly_vifs/vif_gear_cor_nov.csv", row.names = TRUE)
vif_gear_cor_nov <- read.csv("../output/bio/vif/monthly_vifs/vif_gear_cor_nov.csv", header = TRUE)
vif_gear_cor_nov$GVIF2Dfsq <- vif_gear_cor_nov$GVIF..1..2.Df..^2
write.csv(vif_gear_cor_nov, "../output/bio/vif/monthly_vifs/vif_gear_cor_nov.csv", row.names = TRUE)
vif_gear_cor_nov
#without gear
vif_nogear_cor_nov <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = novpresab))
write.csv(vif_nogear_cor_nov, "../output/bio/vif/monthly_vifs/vif_nogear_cor_nov.csv", row.names = TRUE)
vif_nogear_cor_nov
temp_depth salinity_depth o2_depth chl_surface nao_sample nao_prev nao_winter amo_sample amo_winter
1.598138 1.491446 1.730198 1.311339 1.363302 1.207681 1.072291 1.626908 1.685992
#with gear
vif_gear_cor_dec <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = decpresab))
write.csv(vif_gear_cor_dec, "../output/bio/vif/monthly_vifs/vif_gear_cor_dec.csv", row.names = TRUE)
vif_gear_cor_dec
temp_depth salinity_depth o2_depth chl_surface gear nao_sample nao_prev nao_winter amo_sample amo_winter
5.929754 16.230010 8.351577 1.565082 1.320044 1.869436 1.405118 1.596288 1.375816 1.327107
#without gear
vif_nogear_cor_dec <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = decpresab))
write.csv(vif_nogear_cor_dec, "../output/bio/vif/monthly_vifs/vif_nogear_cor_dec.csv", row.names = TRUE)
vif_nogear_cor_dec
temp_depth salinity_depth o2_depth chl_surface nao_sample nao_prev nao_winter amo_sample amo_winter
1.515588 1.873634 2.176190 1.436543 1.840590 1.374077 1.532668 1.245253 1.305000
in the presences, which rows are missing either temp_depth, salinity_depth, or o2_depth?
fmatch("o2_depth", names(presencemerging)) #32
[1] 32
fmatch("salinity_depth", names(presencemerging)) #34
[1] 34
fmatch("temp_depth", names(presencemerging)) #37
[1] 37
presence_wdepth_noo2 <- presence[is.na(presence$o2_depth), ]
nrow(presence_wdepth_noo2) #just to check it has mapped
[1] 3098
presence_wdepth_nosalinity <- presence[is.na(presence$salinity_depth), ]
nrow(presence_wdepth_nosalinity) #just to check it has mapped
[1] 3729
presence_wdepth_notemp <- presence[is.na(presence$temp_depth), ]
nrow(presence_wdepth_notemp) #just to check it has mapped
[1] 3729
ok remove all rows where temp_depth is missing (3729 rows)
presab_missingvals <- presab[!is.na(presab$temp_depth), ]
nrow(presab_missingvals) #130299 - correct
[1] 126570
check for missing vals
presence_wdepth_noo2 <- presab_missingvals[is.na(presab_missingvals$o2_depth), ]
nrow(presence_wdepth_noo2) #just to check it has mapped
[1] 210
presence_wdepth_nosalinity <- presab_missingvals[is.na(presab_missingvals$salinity_depth), ]
nrow(presence_wdepth_nosalinity) #just to check it has mapped
[1] 0
presence_wdepth_notemp <- presab_missingvals[is.na(presab_missingvals$temp_depth), ]
nrow(presence_wdepth_notemp) #just to check it has mapped
[1] 0
ok now remove row where o2_depth is missing
presab_missingvals <- presab_missingvals[!is.na(presab_missingvals$o2_depth), ]
nrow(presab_missingvals) #130299 - correct
[1] 126360
ok as summaries observations per month
and before it was…
just check the obs that you removed (saved as presence_na.csv) to see if the reported depth is deeper than the gebco derrived bottom depth
ok potentially i might be able to claw back 150 points…im not sure its worth it
maxent?
library("raster")
Loading required package: sp
LS0tDQp0aXRsZTogIkRhdGEgRXhwbG9yYXRpb24iDQphdXRob3I6ICJTYW1hbnRoYSBBbmRyZXdzIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazogDQogICAgZmlnX2hlaWdodDogNw0KICAgIGZpZ193aWR0aDogMTANCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCiMgT3ZlcnZpZXcNCkV4cGxvcmF0aW9uIG9mIGFsbCB0aGUgZGF0YSBjb2xsZWN0ZWQgb24gdGhlIHByZXNlbmNlIHBvaW50cyArIHJhbmRvbWx5IGdlbmVyYXRlZCBiYWNrZ3JvdW5kIHBvaW50cw0KDQpBIG5vdGUgdG8gYW55b25lIHdobyBtaWdodCBoYXBwZW4gdG8gc3R1bWJsZSBhY3Jvc3MgdGhpcy4uLiBJIGFtIGEgYmVnaW5uZXIgaW4gUiBhbmQgaGF2ZSBoYWQgbm8gZXhwb3N1cmUgdG8gc2ltaWxhciBsYW5ndWFnZXMuIEkgZG9uJ3Qga25vdyB3aGF0IEknbSBkb2luZy4gVGhlIGNvZGUgaGVyZWluIGlzIHVubGlrZWx5IHRvIGJlIGVsZWdhbnQgYW5kIHRoZXJlIGFyZSBwcm9iYWJseSBtb3JlIGVmZmljaWVudCB3YXlzIG9mIHJ1bm5pbmcgdGhlIGNvZGUuDQoNCkJ1aWx0IHdpdGggJ3IgZ2V0UnZlcnNpb24oKScuDQoNCiMgUGFja2FnZSBkZXBlbmRlbmNpZXMNCllvdSBjYW4gbG9hZCB0aGVtIHVzaW5nIHRoZSBmb2xsb3dpbmcgY29kZSB3aGljaCB1c2VzIGEgZnVuY3Rpb24gY2FsbGVkIFtpcGFrXShodHRwczovL2dpc3QuZ2l0aHViLmNvbS9zdGV2ZW53b3J0aGluZ3Rvbi8zMTc4MTYzKS4gDQpOb3RlIHRoaXMgZnVuY3Rpb24gY2hlY2tzIHRvIHNlZSBpZiB0aGUgcGFja2FnZXMgYXJlIGluc3RhbGxlZCBmaXJzdC4NClRoZSAiaW5jbHVkZT1GQUxTRSIgc3VwcmVzc2VzIHRoZSBwYWNrYWdlIGluc3RhbGxhdGlvbiB0ZXh0IGFwcGVhcmluZyBpbiB0aGUgZG9jdW1lbnQuLi4NCmBgYHtyIHByZS1pbnN0YWxsIHBhY2thZ2VzLCBpbmNsdWRlPUZBTFNFfQ0KcGFja2FnZXMgPC0gYygicGx5ciIsICJncmFwaGljcyIsICJnZ3Bsb3QyIiwgImNvcnJwbG90IiwgIkZTQSIsICJjYXIiLCAicndvcmxkbWFwIiwgImZhc3RtYXRjaCIpIA0Kc291cmNlKCIuLi9zcmMvaXBhay5SIikNCmlwYWsocGFja2FnZXMpDQpgYGANCg0KIyByZWFkIGluIGFsbCBkYXRhDQoNCmFuZCBzdWJzZXQgaW50byBiYWNrZ3JvdW5kIGFuZCBwcmVzZW5jZXMNCmBgYHtyfQ0KcHJlc2FiIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ByZXNhYl8xMGsuY3N2IiwgaGVhZGVyID0gVFJVRSkNCnByZXNlbmNlIDwtIHN1YnNldChwcmVzYWIsIG9jY3VycmVuY2UgPT0gIjEiKQ0KYmFja2dyb3VuZCA8LSBzdWJzZXQocHJlc2FiLCBvY2N1cnJlbmNlID09ICIwIikNCmBgYA0KDQojIyBVcGRhdGU6IFdobyBzYW1wbGVkIGluIHdoaWNoIHllYXIgYW5kIHdoaWNoIG1vbnRoOg0KDQp5ZWFyDQpgYGB7ciBvYnNlcnZhdGlvbnMgYnkgaW5zdGl0dXRlLXllYXJ9DQppbnN0X2J5X3lyIDwtIHdpdGgocHJlc2VuY2UsIHRhYmxlKHllYXIsIGluc3RpdHV0aW9uY29kZSkpDQp3cml0ZS5jc3YoaW5zdF9ieV95ciwgZmlsZSA9ICIuLi9vdXRwdXQvYmlvL2luc3RpdHV0aW9uY29kZV9ieV95ci5jc3YiKQ0KaW5zdF9ieV95cg0KYGBgDQoNCm1vbnRoDQpgYGB7ciBvYnNlcnZhdGlvbnMgYnkgaW5zdGl0dXRlLW1vbnRofQ0KaW5zdF9ieV9tdCA8LSB3aXRoKHByZXNlbmNlLCB0YWJsZShtb250aCwgaW5zdGl0dXRpb25jb2RlKSkNCndyaXRlLmNzdihpbnN0X2J5X210LCBmaWxlID0gIi4uL291dHB1dC9iaW8vaW5zdGl0dXRpb25jb2RlX2J5X210aC5jc3YiKQ0KaW5zdF9ieV9tdA0KYGBgDQoNCmFuZCBqdXN0IGEgeWVhci1tb250aCB0YWJsZQ0KYGBge3Igb2JzZXJ2YXRpb25zIGJ5IHllYXItbW9udGh9DQp5ZWFyX2J5X210IDwtIHdpdGgocHJlc2VuY2UsIHRhYmxlKHllYXIsIG1vbnRoKSkNCndyaXRlLmNzdih5ZWFyX2J5X210LCBmaWxlID0gIi4uL291dHB1dC9iaW8veWVhcl9ieV9tdGguY3N2IikNCnllYXJfYnlfbXQNCmBgYA0KDQoNCg0KIyMgZW52aXJvbm1lbnRhbCBjb3JyZWxhdGVzDQoNCjEpIEdldCB0aGUgbWF4LCBtaW4sIGFuIG1lYW4gdmFsdWVzIGFuZCBhZGQgaW50byBhIGRhdGFmcmFtZQ0KDQpUZW1wZXJhdHVyZQ0KYGBge3J9DQp0ZW1wX2RlcHRoX21heCA8LSBtYXgocHJlc2VuY2UkdGVtcF9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KdGVtcF9kZXB0aF9taW4gPC0gbWluKHByZXNlbmNlJHRlbXBfZGVwdGgsIG5hLnJtID0gVFJVRSkNCnRlbXBfZGVwdGhfbWVhbiA8LSBtZWFuKHByZXNlbmNlJHRlbXBfZGVwdGgsIG5hLnJtID0gVFJVRSkNCnRlbXBfc3VyZmFjZV9tYXggPC0gbWF4KHByZXNlbmNlJHRlbXBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KdGVtcF9zdXJmYWNlX21pbiA8LSBtaW4ocHJlc2VuY2UkdGVtcF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQp0ZW1wX3N1cmZhY2VfbWVhbiA8LSBtZWFuKHByZXNlbmNlJHRlbXBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNClNhbGluaXR5DQpgYGB7cn0NCnNhbF9kZXB0aF9tYXggPC0gbWF4KHByZXNlbmNlJHNhbGluaXR5X2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpzYWxfZGVwdGhfbWluIDwtIG1pbihwcmVzZW5jZSRzYWxpbml0eV9kZXB0aCwgbmEucm0gPSBUUlVFKQ0Kc2FsX2RlcHRoX21lYW4gPC0gbWVhbihwcmVzZW5jZSRzYWxpbml0eV9kZXB0aCwgbmEucm0gPSBUUlVFKQ0Kc2FsX3N1cmZhY2VfbWF4IDwtIG1heChwcmVzZW5jZSRzYWxpbml0eV9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpzYWxfc3VyZmFjZV9taW4gPC0gbWluKHByZXNlbmNlJHNhbGluaXR5X3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNhbF9zdXJmYWNlX21lYW4gPC0gbWVhbihwcmVzZW5jZSRzYWxpbml0eV9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpgYGANCg0KQ2hsDQpgYGB7cn0NCmNobF9kZXB0aF9tYXggPC0gbWF4KHByZXNlbmNlJGNobF9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KY2hsX2RlcHRoX21pbiA8LSBtaW4ocHJlc2VuY2UkY2hsX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpjaGxfZGVwdGhfbWVhbiA8LSBtZWFuKHByZXNlbmNlJGNobF9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KY2hsX3N1cmZhY2VfbWF4IDwtIG1heChwcmVzZW5jZSRjaGxfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KY2hsX3N1cmZhY2VfbWluIDwtIG1pbihwcmVzZW5jZSRjaGxfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KY2hsX3N1cmZhY2VfbWVhbiA8LSBtZWFuKHByZXNlbmNlJGNobF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpgYGANCg0KTzINCmBgYHtyfQ0KbzJfZGVwdGhfbWF4IDwtIG1heChwcmVzZW5jZSRvMl9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KbzJfZGVwdGhfbWluIDwtIG1pbihwcmVzZW5jZSRvMl9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KbzJfZGVwdGhfbWVhbiA8LSBtZWFuKHByZXNlbmNlJG8yX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpvMl9zdXJmYWNlX21heCA8LSBtYXgocHJlc2VuY2UkbzJfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KbzJfc3VyZmFjZV9taW4gPC0gbWluKHByZXNlbmNlJG8yX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCm8yX3N1cmZhY2VfbWVhbiA8LSBtZWFuKHByZXNlbmNlJG8yX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCmBgYA0KDQpNTFANCmBgYHtyfQ0KbWxwX3N1cmZhY2VfbWF4IDwtIG1heChwcmVzZW5jZSRtbHBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KbWxwX3N1cmZhY2VfbWluIDwtIG1pbihwcmVzZW5jZSRtbHBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KbWxwX3N1cmZhY2VfbWVhbiA8LSBtZWFuKHByZXNlbmNlJG1scF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpgYGANCg0KU1NIDQpgYGB7cn0NCnNzaF9zdXJmYWNlX21heCA8LSBtYXgocHJlc2VuY2Ukc3NoX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNzaF9zdXJmYWNlX21pbiA8LSBtaW4ocHJlc2VuY2Ukc3NoX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNzaF9zdXJmYWNlX21lYW4gPC0gbWVhbihwcmVzZW5jZSRzc2hfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNCmNyZWF0ZSBtYXRyaXgNCmBgYHtyfQ0KdGQgPC0gYyh0ZW1wX2RlcHRoX21heCwgdGVtcF9kZXB0aF9taW4sIHRlbXBfZGVwdGhfbWVhbikNCnRzIDwtIGModGVtcF9zdXJmYWNlX21heCwgdGVtcF9zdXJmYWNlX21pbiwgdGVtcF9zdXJmYWNlX21lYW4pDQpzZCA8LSBjKHNhbF9kZXB0aF9tYXgsIHNhbF9kZXB0aF9taW4sIHNhbF9kZXB0aF9tZWFuKQ0Kc3MgPC0gYyhzYWxfc3VyZmFjZV9tYXgsIHNhbF9zdXJmYWNlX21pbiwgc2FsX3N1cmZhY2VfbWVhbikNCmNkIDwtIGMoc2FsX2RlcHRoX21heCwgc2FsX2RlcHRoX21pbiwgc2FsX2RlcHRoX21lYW4pDQpjcyA8LSBjKHNhbF9zdXJmYWNlX21heCwgc2FsX3N1cmZhY2VfbWluLCBzYWxfc3VyZmFjZV9tZWFuKQ0Kb2QgPC0gYyhvMl9kZXB0aF9tYXgsIG8yX2RlcHRoX21pbiwgbzJfZGVwdGhfbWVhbikNCm9zIDwtIGMobzJfc3VyZmFjZV9tYXgsIG8yX3N1cmZhY2VfbWluLCBvMl9zdXJmYWNlX21lYW4pDQptbHAgPC0gYyhtbHBfc3VyZmFjZV9tYXgsIG1scF9zdXJmYWNlX21pbiwgbWxwX3N1cmZhY2VfbWVhbikNCnNzaCA8LSBjKHNzaF9zdXJmYWNlX21heCwgc3NoX3N1cmZhY2VfbWluLCBzc2hfc3VyZmFjZV9tZWFuKQ0KZW52X3N0YXRzIDwtIHJiaW5kKHRkLCB0cywgc2QsIHNzLCBjZCwgY3MsIG9kLCBvcywgbWxwLCBzc2gpDQpyb3cubmFtZXMoZW52X3N0YXRzKSA8LSBjKCJUZW1wIERlcHRoIiwgIlRlbXAgU3VyZmFjZSIsICJTYWxpbml0eSBEZXB0aCIsICJTYWxpbml0eSBTdXJmYWNlIiwgIkNobCBEZXB0aCIsICJDaGwgU3VyZmFjZSIsICJPeHlnZW4gRGVwdGgiLCAiT3h5Z2VuIFN1cmZhY2UiLCAiTUxQIiwgIlNTSCIpIA0KY29sbmFtZXMoZW52X3N0YXRzKSA8LSBjKCJNYXgiLCAiTWluIiwgIk1lYW4iKQ0Kd3JpdGUuY3N2KGVudl9zdGF0cywgIi4uL291dHB1dC9lbnYvZW52X2NvcnJlbGF0ZXNfYmFzaWNfc3RhdHMuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCmVudl9zdGF0cw0KYGBgDQoNCkhtbSBzb21lIHBvdGVudGlhbGx5IHN1c3BpY2lvdXMgdmFsdWVzIGhlcmUgaW4NCi0gT3h5Z2VuIERlcHRoIG1pbg0KLSBtbHAgIE1heA0KYW5kIG1heWJlIGFsc28NCi0gU2FsaW5pdHkgRGVwdGggbWluDQotIFNhbGluaXR5IFN1cmZhY2UgbWluDQotIENITCBkZXB0aCBtaW4NCi0gQ0hMIGRlcHRoIG1heA0KDQpsZXRzIGp1c3Qgc2VlIHdoZXJlIHRoZXNlIHZhbHVlcyBhcHBlYXIgYW5kIGNoZWNrIHRoZSBuZXRjZGYgbGF5ZXJzLiBOb3RlIEkgd2lsbCBjaGVjayB0aGVzZSB2YWx1ZXMgaW4gY3lnd2luIHVzaW5nIHRoZSBjZG8gb3BlcmF0b3IgaW5mb3Ygb24gdGhlIG5ldGNkZnMgKHRvIGVuc3VyZSB0aGVyZSB3YXMgbm8gaXNzdWUgd2l0aCBwcm9jZXNzaW5nIGluIFIpLiANCg0KDQpnZXQgdGhlIHllYXIgYW5kIG1vbnRoIHRoZXNlIHZhbHVlcyBhcHBlYXJlZCBpbg0KYGBge3J9DQpvMmRfY2hlY2tfeXIgPC0gc3Vic2V0KHByZXNlbmNlJHllYXIsIHByZXNlbmNlJG8yX2RlcHRoID09IG8yX2RlcHRoX21pbikNCm8yZF9jaGVja19tdGggPC0gc3Vic2V0KHByZXNlbmNlJG1vbnRoLCBwcmVzZW5jZSRvMl9kZXB0aCA9PSBvMl9kZXB0aF9taW4pDQpgYGANCk8yIGRlcHRoIG1pbiBpcyBpbiAyMDA1XzA4DQoNCkFuZCB2YWx1ZSBzZWVtcyBjb3JyZWN0DQoNCmBgYHtyfQ0KbWxwX2NoZWNrX3lyIDwtIHN1YnNldChwcmVzZW5jZSR5ZWFyLCBwcmVzZW5jZSRtbHBfc3VyZmFjZSA9PSBtbHBfc3VyZmFjZV9tYXgpDQptbHBfY2hlY2tfbXRoIDwtIHN1YnNldChwcmVzZW5jZSRtb250aCwgcHJlc2VuY2UkbWxwX3N1cmZhY2UgPT0gbWxwX3N1cmZhY2VfbWF4KQ0KYGBgDQptbHAgbWF4IGluIGluIDIwMDdfMTINCg0KQW5kIHllcyB0aGUgdmFsdWUgc2VlbXMgY29ycmVjdA0KDQpgYGB7cn0NCnNhbGRfY2hlY2tfeXIgPC0gc3Vic2V0KHByZXNlbmNlJHllYXIsIHByZXNlbmNlJHNhbGluaXR5X2RlcHRoID09IHNhbF9kZXB0aF9tYXgpDQpzYWxkX2NoZWNrX210aCA8LSBzdWJzZXQocHJlc2VuY2UkbW9udGgsIHByZXNlbmNlJHNhbGluaXR5X2RlcHRoID09IHNhbF9kZXB0aF9tYXgpDQpgYGANCnllYXIgbW9udGggMjAwMV8wNQ0KDQphbHNvIHNlZW1zIGNvcnJlY3QNCg0KYGBge3J9DQpzYWxzX2NoZWNrX3lyIDwtIHN1YnNldChwcmVzZW5jZSR5ZWFyLCBwcmVzZW5jZSRzYWxpbml0eV9zdXJmYWNlID09IHNhbF9zdXJmYWNlX21pbikNCnNhbHNfY2hlY2tfbXRoIDwtIHN1YnNldChwcmVzZW5jZSRtb250aCwgcHJlc2VuY2Ukc2FsaW5pdHlfc3VyZmFjZSA9PSBzYWxfc3VyZmFjZV9taW4pDQpgYGANCnllYXIgbW9udGggMjE5OThfMDYNCg0Kb2sgYWdhaW4uLi4NCg0KTGVhdmUgdGhlIHJlc3QNCg0KDQojIyBzaW1wbGUgcGxvdHMgb2YgZW52LiBjb3JyZWxhdGVzDQoNCnRlbXBlcmF0dXJlDQpgYGB7cn0NCnBhcihtZnJvdz1jKDEsMikpDQpwbG90KHByZXNlbmNlJHRlbXBfZGVwdGgsIG1haW4gPSAiVGVtcCBhdCBEZXB0aCAoVmFyaW91cykiLCB5bGFiID0gIktlbHZpbiIpDQpwbG90KHByZXNlbmNlJHRlbXBfc3VyZmFjZSwgbWFpbiA9ICJUZW1wIGF0IFN1cmZhY2UiLCB5bGFiID0gIktlbHZpbiIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy90ZW1wZXJhdHVyZV9zaW1wbGVwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQpIbW0gbm90IG5lY2Vzc2FyaWx5IHZlcnkgaGVscGZ1bC4gQnV0IGFueXdheSwgbGV0cyBjYXJyeSBvbg0KDQpzYWxpbml0eQ0KYGBge3J9DQpwYXIobWZyb3c9YygxLDIpKQ0KcGxvdChwcmVzZW5jZSRzYWxpbml0eV9kZXB0aCwgbWFpbiA9ICJTYWxpbml0eSBhdCBEZXB0aCAoVmFyaW91cykiLCB5bGFiID0gIlByYWN0aWNhbCBTYWxpbml0eSBVbml0cyIpDQpwbG90KHByZXNlbmNlJHNhbGluaXR5X3N1cmZhY2UsIG1haW4gPSAiU2FsaW5pdHkgYXQgU3VyZmFjZSIsIHlsYWIgPSAiUHJhY3RpY2FsIFNhbGluaXR5IFVuaXRzIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc2FsaW5pdHlfc2ltcGxlcGxvdC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpDaGxvcm9waHlsbA0KYGBge3J9DQpwYXIobWZyb3c9YygxLDIpKQ0KcGxvdChwcmVzZW5jZSRjaGxfZGVwdGgsIG1haW4gPSAiQ2hsIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAiQ2hsIChtbW9sLm0tMykiKQ0KcGxvdChwcmVzZW5jZSRjaGxfc3VyZmFjZSwgbWFpbiA9ICJDaGwgYXQgU3VyZmFjZSIsIHlsYWIgPSAiQ2hsIChtbW9sLm0tMykiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9jaGxfc2ltcGxlcGxvdC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpPMg0KYGBge3J9DQpwYXIobWZyb3c9YygxLDIpKQ0KcGxvdChwcmVzZW5jZSRvMl9kZXB0aCwgbWFpbiA9ICJEaXNzb2x2ZWQgT3h5Z2VuIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAiQ2hsIChtbW9sLm0tMykiKQ0KcGxvdChwcmVzZW5jZSRvMl9zdXJmYWNlLCBtYWluID0gIkRpc3NvbHZlZCBPeHlnZW4gYXQgU3VyZmFjZSIsIHlsYWIgPSAiTzIgKG1tb2wubS0zKSIpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX3NpbXBsZXBsb3QucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KbWxwDQpgYGB7cn0NCnBsb3QocHJlc2VuY2UkbWxwX3N1cmZhY2UsIG1haW4gPSAiTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIiwgeWxhYiA9ICJEZXB0aCAobSkiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfc2ltcGxlcGxvdC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpTU0gNCmBgYHtyfQ0KcGxvdChwcmVzZW5jZSRzc2hfc3VyZmFjZSwgbWFpbiA9ICJTZWEgU3VyZmFjZSBIZWlnaHQiLCB5bGFiID0gIkhlaWdodCAobSkiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zc2hfc2ltcGxlcGxvdC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpYWFggU0FNIC0gWU9VIFdBTlQgVE8gVEhJTksgQUJPVVQgRE9JTkcgVEhJUyBCWSBERVBUSCBSQVRIRVIgVEhBTiBBTEwgREVQVEhTKQ0KDQpgYGB7cn0NCnVuaXF1ZV9kZXB0aHMgPC0gdW5pcXVlKHByZXNlbmNlJGRlcHRobGF5ZXJubykNCnVuaXF1ZV9kZXB0aGRvcmRlcmVkIDwtIHNvcnQodW5pcXVlX2RlcHRocykgI2p1c3QgcHV0cyB0aGUgbGlzdCBpbiBvZGVyIHdpdGggbm8gTkENCmxlbmd0aCh1bmlxdWVfZGVwdGhkb3JkZXJlZCkNCmBgYA0Kb3VjaCAtIDM5IGxheWVycy4uLiBhIGpvYiBmb3IgYSBib3hwbG90IHByb2JhYmx5DQoNCmBgYHtyfQ0KDQpgYGANCg0KDQoNCiMgZnJlcXVlbmN5IHBsb3RzIG9mIGVudi4gY29ycg0KDQoNCnRlbXBlcmF0dXJlDQpgYGB7cn0NCmhpc3QocHJlc2VuY2UkdGVtcF9zdXJmYWNlLCBtYWluID0gIlRlbXAgYXQgU3VyZmFjZSIsIHhsYWIgPSAiS2VsdmluIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX3N1cmZhY2VfaGlzdG9ncmFtLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KaGlzdChwcmVzZW5jZSR0ZW1wX2RlcHQsIG1haW4gPSAiVGVtcCBhdCBEZXB0aCIsIHhsYWIgPSAiS2VsdmluIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2RlcHRoX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpjaGwNCmBgYHtyfQ0KaGlzdChwcmVzZW5jZSRjaGxfc3VyZmFjZSwgbWFpbiA9ICJDaGxvcm9waHlsbCBhdCBTdXJmYWNlIiwgeGxhYiA9ICJDaGxvcm9waHlsbCBDb25jZW50cmF0aW9ucyAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9zdXJmYWNlX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmhpc3QocHJlc2VuY2UkY2hsX2RlcHRoLCBtYWluID0gIkNobG9yb3BoeWxsIGF0IE9ic2VydmF0aW9uIERlcHRoIiwgeGxhYiA9ICJDaGxvcm9waHlsbCBDb25jZW50cmF0aW9ucyAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9kZXB0aF9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0Kc2FsaW5pdHkNCmBgYHtyfQ0KaGlzdChwcmVzZW5jZSRzYWxpbml0eV9zdXJmYWNlLCBtYWluID0gIlNhbGluaXR5IGF0IFN1cmZhY2UiLCB4bGFiID0gIlNhbGluaXR5IFByYWN0aWNhbCBTYWxpbml0eSBVbml0IChQU1UpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbF9zdXJmYWNlX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmhpc3QocHJlc2VuY2Ukc2FsaW5pdHlfZGVwdGgsIG1haW4gPSAiU2FsaW5pdHkgYXQgT2JzZXJ2YXRpb24gRGVwdGgiLCB4bGFiID0gIlNhbGluaXR5IFByYWN0aWNhbCBTYWxpbml0eSBVbml0IChQU1UpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbF9kZXB0aF9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0Kb3h5Z2VuDQpgYGB7cn0NCmhpc3QocHJlc2VuY2UkbzJfc3VyZmFjZSwgbWFpbiA9ICJEaXNzb2x2ZWQgT3h5Z2VuIGF0IFN1cmZhY2UiLCB4bGFiID0gIk1vbGUgQ29uY2VudHJhdGlvbiBvZiBEaXNzb2x2ZWQgT3h5Z2VuIGluIFNlYSBXYXRlciAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX3N1cmZhY2VfaGlzdG9ncmFtLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KaGlzdChwcmVzZW5jZSRvMl9kZXB0aCwgbWFpbiA9ICJEaXNzb2x2ZWQgT3h5Z2VuIGF0IE9ic2VydmF0aW9uIERlcHRoIiwgeGxhYiA9ICJNb2xlIENvbmNlbnRyYXRpb24gb2YgRGlzc29sdmVkIE94eWdlbiBpbiBTZWEgV2F0ZXIgKG1tb2wubS0zKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9vMl9kZXB0aF9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KTUxQDQpgYGB7cn0NCmhpc3QocHJlc2VuY2UkbWxwLCBtYWluID0gIk1peGVkIExheWVyIFRoaWNrbmVzcyBhdCBPYnNlcnZhdGlvbiIsIHhsYWIgPSAiTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIChtKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfc3VyZmFjZV9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0Kc3NoDQpgYGB7cn0NCmhpc3QocHJlc2VuY2Ukc3NoLCBtYWluID0gIlNlYSBTdXJmYWNlIEhlaWdodCBhdCBPYnNlcnZhdGlvbiIsIHhsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zc2hfc3VyZmFjZV9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KDQojIyBzaW1wbGUgYm94cGxvdHMgb2YgZW52LiBjb3JyDQoNClNhbWUgYXMgYWJvdmUgYnV0IHdpdGggYm94cGxvdHMgKG1heSBwcm92aWRlIHNvbWUgbW9yZSB1c2VmdWwgaW5mbykNCg0KDQoNCmluZGl2aWR1YWwgcGxvdHMgb2YgZWFjaCB2YXJpYWJsZSANCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkNCmJveHBsb3QocHJlc2VuY2UkdGVtcF9kZXB0aCwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBEZXB0aCAoVmFyaW91cykiLCB5bGFiID0gIktlbHZpbiIpDQpib3hwbG90KHByZXNlbmNlJHRlbXBfc3VyZmFjZSwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBTdXJmYWNlIiwgeWxhYiA9ICJLZWx2aW4iKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcF9ib3hwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpwYXIobWZyb3c9YygxLDIpKQ0KYm94cGxvdChwcmVzZW5jZSRzYWxpbml0eV9kZXB0aCwgbWFpbiA9ICJTYWxpbml0eSBhdCBEZXB0aCAoVmFyaW91cykiLCB5bGFiID0gIlBTVSIpDQpib3hwbG90KHByZXNlbmNlJHNhbGluaXR5X3N1cmZhY2UsIG1haW4gPSAiU2FsaW5pdHkgYXQgU3VyZmFjZSIsIHlsYWIgPSAiUFNVIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbGluaXR5X2JveHBsb3QucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCnBhcihtZnJvdz1jKDEsMikpDQpib3hwbG90KHByZXNlbmNlJG8yX2RlcHRoLCBtYWluID0gIk8yIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAibW1vbC5tLTMiKQ0KYm94cGxvdChwcmVzZW5jZSRvMl9zdXJmYWNlLCBtYWluID0gIk8yIGF0IFN1cmZhY2UiLCB5bGFiID0gIm1tb2wubS0zIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX2JveHBsb3QucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCnBhcihtZnJvdz1jKDEsMikpDQpib3hwbG90KHByZXNlbmNlJGNobF9kZXB0aCwgbWFpbiA9ICJDaGxvcnBoeWxsIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAibW1vbC5tLTMiKQ0KYm94cGxvdChwcmVzZW5jZSRjaGxfc3VyZmFjZSwgbWFpbiA9ICJDaGxvcnBoeWxsIGF0IFN1cmZhY2UiLCB5bGFiID0gIm1tb2wubS0zIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9ib3hwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpwYXIobWZyb3c9YygxLDIpKQ0KYm94cGxvdChwcmVzZW5jZSRtbHBfc3VyZmFjZSwgbWFpbiA9ICJEZW5zaXR5IE1peGVkIExheWVyIFRoaWNrbmVzcyIsIHlsYWIgPSAibWV0ZXJzIikNCmJveHBsb3QocHJlc2VuY2Ukc3NoX3N1cmZhY2UsIG1haW4gPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IiwgeWxhYiA9ICJtZXRlcnMiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbWxwX3NzaF9ib3hwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSR0ZW1wX2RlcHRoIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBPYnNlcnZhdGlvbiBEZXB0aCBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcGVyYXR1cmVfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRjaGxfZGVwdGggfiBwcmVzZW5jZSRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiQ2hsb3JvcGh5bGwgQ29uY2VudHJhdGlvbnMgKG1tb2wubS0zKSIsIG1haW4gPSAiQ2hsb3JvcGh5bGwgYXQgT2JzZXJ2YXRpb24gRGVwdGggcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobG9yb3BoeWxsX2JveHBsb3RfZGVwdF9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2Ukc2FsaW5pdHlfZGVwdGggfiBwcmVzZW5jZSRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IE9ic2VydmF0aW9uIERlcHRoIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zYWxpbml0eV9ib3hwbG90X2RlcHRfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJG8yX2RlcHRoIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIk1vbGUgQ29uY2VudHJhdGlvbiBvZiBEaXNzb2x2ZWQgT3h5Z2VuIGluIFNlYSBXYXRlciAobW1vbC5tLTMpIiwgbWFpbiA9ICJEaXNzb2x2ZWQgT3h5Z2VuIGF0IE9ic2VydmF0aW9uIERlcHRoIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9vMl9ib3hwbG90X2RlcHRfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJG1scF9zdXJmYWNlIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIk1peGVkIExheWVyIFRoaWNrbmVzcyAobSkiLCBtYWluID0gIk1peGVkIExheWVyIFRoaWNrbmVzcyBhdCBPYnNlcnZhdGlvbiBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbWxwX2JveHBsb3RfZGVwdF9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2Ukc3NoX3N1cmZhY2UgfiBwcmVzZW5jZSRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIsIG1haW4gPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IGF0IE9ic2VydmF0aW9uIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zc2hfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSR0ZW1wX2RlcHRoIH4gcHJlc2VuY2UkeWVhciwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJUZW1wZXJhdHVyZSAoS2VsdmluKSIsIG1haW4gPSAiVGVtcGVyYXR1cmUgYXQgT2JzZXJ2YXRpb24gRGVwdGggcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcGVyYXR1cmVfYm94cGxvdF9kZXB0X3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJGNobF9kZXB0aCB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiQ2hsb3JvcGh5bGwgQ29uY2VudHJhdGlvbnMgKG1tb2wubS0zKSIsIG1haW4gPSAiQ2hsb3JvcGh5bGwgYXQgT2JzZXJ2YXRpb24gRGVwdGggcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvY2hsX2JveHBsb3RfZGVwdF95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRzYWxpbml0eV9kZXB0aCB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IE9ic2VydmF0aW9uIERlcHRoIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbGluaXR5X2JveHBsb3RfZGVwdF95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRvMl9kZXB0aCB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiTW9sZSBDb25jZW50cmF0aW9uIG9mIERpc3NvbHZlZCBPeHlnZW4gaW4gU2VhIFdhdGVyIChtbW9sLm0tMykiLCBtYWluID0gIkRpc3NvbHZlZCBPeHlnZW4gYXQgT2JzZXJ2YXRpb24gRGVwdGggcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvb3h5Z2VuX2JveHBsb3RfZGVwdF95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRtbHAgfiBwcmVzZW5jZSR5ZWFyLCB4bGFiID0gIlllYXIiLCB5bGFiID0gIk1peGVkIExheWVyIFRoaWNrbmVzcyAobSkiLCBtYWluID0gIk1peGVkIExheWVyIFRoaWNrbmVzcyBhdCBPYnNlcnZhdGlvbiBwZXIgWWVhciIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfYm94cGxvdF9kZXB0X3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJHNzaCB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIsIG1haW4gPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IGF0IE9ic2VydmF0aW9uIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NzaF9ib3hwbG90X2RlcHRfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2UkdGVtcF9zdXJmYWNlIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBPYnNlcnZhdGlvbiAoU3VyZmFjZSkgcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2UkY2hsX3N1cmZhY2UgfiBwcmVzZW5jZSRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiQ2hsb3JvcGh5bGwgQ29uY2VudHJhdGlvbnMgKG1tb2wubS0zKSIsIG1haW4gPSAiQ2hsb3JvcGh5bGwgYXQgT2JzZXJ2YXRpb24gKFN1cmZhY2UpIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9jaGxvcm9waHlsbF9ib3hwbG90X3N1cmZhY2VfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJHNhbGluaXR5X3N1cmZhY2UgfiBwcmVzZW5jZSRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IE9ic2VydmF0aW9uIChTdXJmYWNlKSBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc2FsaW5pdHlfYm94cGxvdF9zdXJmYWNlX21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRvMl9zdXJmYWNlIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIk1vbGUgQ29uY2VudHJhdGlvbiBvZiBEaXNzb2x2ZWQgT3h5Z2VuIGluIFNlYSBXYXRlciAobW1vbC5tLTMpIiwgbWFpbiA9ICJEaXNzb2x2ZWQgT3h5Z2VuIGF0IE9ic2VydmF0aW9uIChTdXJmYWNlKSBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbzJfYm94cGxvdF9zdXJmYWNlX21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRtbHBfc3VyZmFjZSB+IHByZXNlbmNlJG1vbnRoLCB4bGFiID0gIm1vbnRoIiwgeWxhYiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgKG0pIiwgbWFpbiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgYXQgT2JzZXJ2YXRpb24gcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL21scF9ib3hwbG90X3N1cmZhY2VfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJHNzaF9zdXJmYWNlIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIlNlYSBTdXJmYWNlIEhlaWdodCAobSkiLCBtYWluID0gIlNlYSBTdXJmYWNlIEhlaWdodCBhdCBPYnNlcnZhdGlvbiBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc3NoX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2UkdGVtcF9zdXJmYWNlIH4gcHJlc2VuY2UkeWVhciwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJUZW1wZXJhdHVyZSAoS2VsdmluKSIsIG1haW4gPSAiVGVtcGVyYXR1cmUgYXQgT2JzZXJ2YXRpb24gKFN1cmZhY2UpIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JveHBsb3Rfc3VyZmFjZV95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRjaGxfc3VyZmFjZSB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiQ2hsb3JvcGh5bGwgQ29uY2VudHJhdGlvbnMgKG1tb2wubS0zKSIsIG1haW4gPSAiQ2hsb3JvcGh5bGwgYXQgT2JzZXJ2YXRpb24gKFN1cmZhY2UpIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9ib3hwbG90X3N1cmZhY2VfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2Ukc2FsaW5pdHlfc3VyZmFjZSB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IE9ic2VydmF0aW9uIChTdXJmYWNlKSBwZXIgWWVhciIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zYWxpbml0eV9ib3hwbG90X3N1cmZhY2VfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2UkbzJfc3VyZmFjZSB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiTW9sZSBDb25jZW50cmF0aW9uIG9mIERpc3NvbHZlZCBPeHlnZW4gaW4gU2VhIFdhdGVyIChtbW9sLm0tMykiLCBtYWluID0gIkRpc3NvbHZlZCBPeHlnZW4gYXQgT2JzZXJ2YXRpb24gKFN1cmZhY2UpIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL294eWdlbl9ib3hwbG90X3N1cmZhY2VfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQoNCiMgYmFja2dyb3VuZCBwb2ludHMNCg0KDQojIGVudmlyb25tZW50YWwgY29ycmVsYXRlcw0KDQoxKSBHZXQgdGhlIG1heCwgbWluLCBhbiBtZWFuIHZhbHVlcyBhbmQgYWRkIGludG8gYSBkYXRhZnJhbWUNCg0KVGVtcGVyYXR1cmUNCmBgYHtyfQ0KdGVtcF9kZXB0aF9tYXhfYmFjayA8LSBtYXgoYmFja2dyb3VuZCR0ZW1wX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQp0ZW1wX2RlcHRoX21pbl9iYWNrIDwtIG1pbihiYWNrZ3JvdW5kJHRlbXBfZGVwdGgsIG5hLnJtID0gVFJVRSkNCnRlbXBfZGVwdGhfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCR0ZW1wX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQp0ZW1wX3N1cmZhY2VfbWF4X2JhY2sgPC0gbWF4KGJhY2tncm91bmQkdGVtcF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQp0ZW1wX3N1cmZhY2VfbWluX2JhY2sgPC0gbWluKGJhY2tncm91bmQkdGVtcF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQp0ZW1wX3N1cmZhY2VfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCR0ZW1wX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCmBgYA0KDQpTYWxpbml0eQ0KYGBge3J9DQpzYWxfZGVwdGhfbWF4X2JhY2sgPC0gbWF4KGJhY2tncm91bmQkc2FsaW5pdHlfZGVwdGgsIG5hLnJtID0gVFJVRSkNCnNhbF9kZXB0aF9taW5fYmFjayA8LSBtaW4oYmFja2dyb3VuZCRzYWxpbml0eV9kZXB0aCwgbmEucm0gPSBUUlVFKQ0Kc2FsX2RlcHRoX21lYW5fYmFjayA8LSBtZWFuKGJhY2tncm91bmQkc2FsaW5pdHlfZGVwdGgsIG5hLnJtID0gVFJVRSkNCnNhbF9zdXJmYWNlX21heF9iYWNrIDwtIG1heChiYWNrZ3JvdW5kJHNhbGluaXR5X3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNhbF9zdXJmYWNlX21pbl9iYWNrIDwtIG1pbihiYWNrZ3JvdW5kJHNhbGluaXR5X3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNhbF9zdXJmYWNlX21lYW5fYmFjayA8LSBtZWFuKGJhY2tncm91bmQkc2FsaW5pdHlfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNCkNobA0KYGBge3J9DQpjaGxfZGVwdGhfbWF4X2JhY2sgPC0gbWF4KGJhY2tncm91bmQkY2hsX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpjaGxfZGVwdGhfbWluX2JhY2sgPC0gbWluKGJhY2tncm91bmQkY2hsX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpjaGxfZGVwdGhfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCRjaGxfZGVwdGgsIG5hLnJtID0gVFJVRSkNCmNobF9zdXJmYWNlX21heF9iYWNrIDwtIG1heChiYWNrZ3JvdW5kJGNobF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpjaGxfc3VyZmFjZV9taW5fYmFjayA8LSBtaW4oYmFja2dyb3VuZCRjaGxfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KY2hsX3N1cmZhY2VfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCRjaGxfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNCk8yDQpgYGB7cn0NCm8yX2RlcHRoX21heF9iYWNrIDwtIG1heChiYWNrZ3JvdW5kJG8yX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpvMl9kZXB0aF9taW5fYmFjayA8LSBtaW4oYmFja2dyb3VuZCRvMl9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KbzJfZGVwdGhfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCRvMl9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KbzJfc3VyZmFjZV9tYXhfYmFjayA8LSBtYXgoYmFja2dyb3VuZCRvMl9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpvMl9zdXJmYWNlX21pbl9iYWNrIDwtIG1pbihiYWNrZ3JvdW5kJG8yX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCm8yX3N1cmZhY2VfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCRvMl9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpgYGANCg0KTUxQDQpgYGB7cn0NCm1scF9zdXJmYWNlX21heF9iYWNrIDwtIG1heChiYWNrZ3JvdW5kJG1scF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQptbHBfc3VyZmFjZV9taW5fYmFjayA8LSBtaW4oYmFja2dyb3VuZCRtbHBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KbWxwX3N1cmZhY2VfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCRtbHBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNClNTSA0KYGBge3J9DQpzc2hfc3VyZmFjZV9tYXhfYmFjayA8LSBtYXgoYmFja2dyb3VuZCRzc2hfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0Kc3NoX3N1cmZhY2VfbWluX2JhY2sgPC0gbWluKGJhY2tncm91bmQkc3NoX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNzaF9zdXJmYWNlX21lYW5fYmFjayA8LSBtZWFuKGJhY2tncm91bmQkc3NoX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCmBgYA0KDQpjcmVhdGUgbWF0cml4DQpgYGB7cn0NCnRkYiA8LSBjKHRlbXBfZGVwdGhfbWF4X2JhY2ssIHRlbXBfZGVwdGhfbWluX2JhY2ssIHRlbXBfZGVwdGhfbWVhbl9iYWNrKQ0KdHNiIDwtIGModGVtcF9zdXJmYWNlX21heF9iYWNrLCB0ZW1wX3N1cmZhY2VfbWluX2JhY2ssIHRlbXBfc3VyZmFjZV9tZWFuX2JhY2spDQpzZGIgPC0gYyhzYWxfZGVwdGhfbWF4X2JhY2ssIHNhbF9kZXB0aF9taW5fYmFjaywgc2FsX2RlcHRoX21lYW5fYmFjaykNCnNzYiA8LSBjKHNhbF9zdXJmYWNlX21heF9iYWNrLCBzYWxfc3VyZmFjZV9taW5fYmFjaywgc2FsX3N1cmZhY2VfbWVhbl9iYWNrKQ0KY2RiIDwtIGMoc2FsX2RlcHRoX21heF9iYWNrLCBzYWxfZGVwdGhfbWluX2JhY2ssIHNhbF9kZXB0aF9tZWFuX2JhY2spDQpjc2IgPC0gYyhzYWxfc3VyZmFjZV9tYXhfYmFjaywgc2FsX3N1cmZhY2VfbWluX2JhY2ssIHNhbF9zdXJmYWNlX21lYW5fYmFjaykNCm9kYiA8LSBjKG8yX2RlcHRoX21heF9iYWNrLCBvMl9kZXB0aF9taW5fYmFjaywgbzJfZGVwdGhfbWVhbl9iYWNrKQ0Kb3NiIDwtIGMobzJfc3VyZmFjZV9tYXhfYmFjaywgbzJfc3VyZmFjZV9taW5fYmFjaywgbzJfc3VyZmFjZV9tZWFuX2JhY2spDQptbHBiIDwtIGMobWxwX3N1cmZhY2VfbWF4X2JhY2ssIG1scF9zdXJmYWNlX21pbl9iYWNrLCBtbHBfc3VyZmFjZV9tZWFuX2JhY2spDQpzc2hiIDwtIGMoc3NoX3N1cmZhY2VfbWF4X2JhY2ssIHNzaF9zdXJmYWNlX21pbl9iYWNrLCBzc2hfc3VyZmFjZV9tZWFuX2JhY2spDQplbnZfc3RhdHNfYmFjayA8LSByYmluZCh0ZGIsIHRzYiwgc2RiLCBzc2IsIGNkYiwgY3NiLCBvZGIsIG9zYiwgbWxwYiwgc3NoYikNCnJvdy5uYW1lcyhlbnZfc3RhdHNfYmFjaykgPC0gYygiVGVtcCBEZXB0aCIsICJUZW1wIFN1cmZhY2UiLCAiU2FsaW5pdHkgRGVwdGgiLCAiU2FsaW5pdHkgU3VyZmFjZSIsICJDaGwgRGVwdGgiLCAiQ2hsIFN1cmZhY2UiLCAiT3h5Z2VuIERlcHRoIiwgIk94eWdlbiBTdXJmYWNlIiwgIk1MUCIsICJTU0giKSANCmNvbG5hbWVzKGVudl9zdGF0c19iYWNrKSA8LSBjKCJNYXgiLCAiTWluIiwgIk1lYW4iKQ0Kd3JpdGUuY3N2KGVudl9zdGF0c19iYWNrLCAiLi4vb3V0cHV0L2Vudi9lbnZfY29ycmVsYXRlc19iYWNrZ3JvdW5kX2Jhc2ljX3N0YXRzLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQplbnZfc3RhdHNfYmFjaw0KYGBgDQoNCnRlbXBlcmF0dXJlDQpgYGB7cn0NCnBhcihtZnJvdz1jKDEsMikpDQpwbG90KGJhY2tncm91bmQkdGVtcF9kZXB0aCwgbWFpbiA9ICJCYWNrZ3JvdW5kIFBvaW50cyBUZW1wIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAiS2VsdmluIikNCnBsb3QoYmFja2dyb3VuZCR0ZW1wX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBQb2ludHMgVGVtcCBhdCBTdXJmYWNlIiwgeWxhYiA9ICJLZWx2aW4iKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcGVyYXR1cmVfYmFja2dyb3VuZF9zaW1wbGVwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCg0Kc2FsaW5pdHkNCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkNCnBsb3QoYmFja2dyb3VuZCRzYWxpbml0eV9kZXB0aCwgbWFpbiA9ICJCYWNrZ3JvdW5kIFBvaW50cyBTYWxpbml0eSBhdCBEZXB0aCAoVmFyaW91cykiLCB5bGFiID0gIlByYWN0aWNhbCBTYWxpbml0eSBVbml0cyIpDQpwbG90KGJhY2tncm91bmQkc2FsaW5pdHlfc3VyZmFjZSwgbWFpbiA9ICJCYWNrZ3JvdW5kIFBvaW50cyBTYWxpbml0eSBhdCBTdXJmYWNlIiwgeWxhYiA9ICJQcmFjdGljYWwgU2FsaW5pdHkgVW5pdHMiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zYWxpbml0eV9iYWNrZ3JvdW5kX3NpbXBsZXBsb3QucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KQ2hsb3JvcGh5bGwNCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkNCnBsb3QoYmFja2dyb3VuZCRjaGxfZGVwdGgsIG1haW4gPSAiQmFja2dyb3VuZCBQb2ludHMgQ2hsIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAiQ2hsIChtbW9sLm0tMykiKQ0KcGxvdChiYWNrZ3JvdW5kJGNobF9zdXJmYWNlLCBtYWluID0gIkJhY2tncm91bmQgUG9pbnRzIENobCBhdCBTdXJmYWNlIiwgeWxhYiA9ICJDaGwgKG1tb2wubS0zKSIpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9iYWNrZ3JvdW5kX3NpbXBsZXBsb3QucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KTzINCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkNCnBsb3QoYmFja2dyb3VuZCRvMl9kZXB0aCwgbWFpbiA9ICJCYWNrZ3JvdW5kIFBvaW50cyBEaXNzb2x2ZWQgT3h5Z2VuIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAiQ2hsIChtbW9sLm0tMykiKQ0KcGxvdChiYWNrZ3JvdW5kJG8yX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBQb2ludHMgRGlzc29sdmVkIE94eWdlbiBhdCBTdXJmYWNlIiwgeWxhYiA9ICJPMiAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbzJfYmFja2dyb3VuZF9zaW1wbGVwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCm1scA0KYGBge3J9DQpwbG90KGJhY2tncm91bmQkbWxwX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBQb2ludHMgTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIiwgeWxhYiA9ICJEZXB0aCAobSkiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfYmFja2dyb3VuZF9zaW1wbGVwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNClNTSA0KYGBge3J9DQpwbG90KGJhY2tncm91bmQkc3NoX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBQb2ludHMgU2VhIFN1cmZhY2UgSGVpZ2h0IiwgeWxhYiA9ICJIZWlnaHQgKG0pIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc3NoX2JhY2tncm91bmRfc2ltcGxlcGxvdC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQojIyBmcmVxdWVuY3kgcGxvdHMgb2YgZW52LiBjb3JyDQoNCg0KdGVtcGVyYXR1cmUNCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJHRlbXBfc3VyZmFjZSwgbWFpbiA9ICJCYWNrZ3JvdW5kIFRlbXAgYXQgU3VyZmFjZSIsIHhsYWIgPSAiS2VsdmluIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JhY2tncm91bmRfc3VyZmFjZV9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpoaXN0KGJhY2tncm91bmQkdGVtcF9kZXB0LCBtYWluID0gIkJhY2tncm91bmQgVGVtcCBhdCBEZXB0aCIsIHhsYWIgPSAiS2VsdmluIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JhY2tncm91bmRfZGVwdGhfaGlzdG9ncmFtLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmNobA0KYGBge3J9DQpoaXN0KGJhY2tncm91bmQkY2hsX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBDaGxvcm9waHlsbCBhdCBTdXJmYWNlIiwgeGxhYiA9ICJDaGxvcm9waHlsbCBDb25jZW50cmF0aW9ucyAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9iYWNrZ3JvdW5kX3N1cmZhY2VfaGlzdG9ncmFtLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJGNobF9kZXB0aCwgbWFpbiA9ICJCYWNrZ3JvdW5kIENobG9yb3BoeWxsIGF0IE9ic2VydmF0aW9uIERlcHRoIiwgeGxhYiA9ICJDaGxvcm9waHlsbCBDb25jZW50cmF0aW9ucyAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9iYWNrZ3JvdW5kX2RlcHRoX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpzYWxpbml0eQ0KYGBge3J9DQpoaXN0KGJhY2tncm91bmQkc2FsaW5pdHlfc3VyZmFjZSwgbWFpbiA9ICJCYWNrZ3JvdW5kIFNhbGluaXR5IGF0IFN1cmZhY2UiLCB4bGFiID0gIlNhbGluaXR5IFByYWN0aWNhbCBTYWxpbml0eSBVbml0IChQU1UpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbF9iYWNrZ3JvdW5kX3N1cmZhY2VfaGlzdG9ncmFtLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJHNhbGluaXR5X2RlcHRoLCBtYWluID0gIkJhY2tncm91bmQgU2FsaW5pdHkgYXQgT2JzZXJ2YXRpb24gRGVwdGgiLCB4bGFiID0gIlNhbGluaXR5IFByYWN0aWNhbCBTYWxpbml0eSBVbml0IChQU1UpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbF9iYWNrZ3JvdW5kX2RlcHRoX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpveHlnZW4NCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJG8yX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBEaXNzb2x2ZWQgT3h5Z2VuIGF0IFN1cmZhY2UiLCB4bGFiID0gIk1vbGUgQ29uY2VudHJhdGlvbiBvZiBEaXNzb2x2ZWQgT3h5Z2VuIGluIFNlYSBXYXRlciAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX2JhY2tncm91bmRfc3VyZmFjZV9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpoaXN0KGJhY2tncm91bmQkbzJfZGVwdGgsIG1haW4gPSAiQmFja2dyb3VuZCBEaXNzb2x2ZWQgT3h5Z2VuIGF0IE9ic2VydmF0aW9uIERlcHRoIiwgeGxhYiA9ICJNb2xlIENvbmNlbnRyYXRpb24gb2YgRGlzc29sdmVkIE94eWdlbiBpbiBTZWEgV2F0ZXIgKG1tb2wubS0zKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9vMl9iYWNrZ3JvdW5kX2RlcHRoX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpNTFANCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJG1scCwgbWFpbiA9ICJCYWNrZ3JvdW5kIE1peGVkIExheWVyIFRoaWNrbmVzcyBhdCBPYnNlcnZhdGlvbiIsIHhsYWIgPSAiTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIChtKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfYmFja2dyb3VuZF9zdXJmYWNlX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpzc2gNCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJHNzaCwgbWFpbiA9ICJCYWNrZ3JvdW5kIFNlYSBTdXJmYWNlIEhlaWdodCBhdCBPYnNlcnZhdGlvbiIsIHhsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zc2hfYmFja2dyb3VuZF9zdXJmYWNlX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQojIyBzaW1wbGUgYm94cGxvdHMgb2YgZW52LiBjb3JyDQoNClNhbWUgYXMgYWJvdmUgYnV0IHdpdGggYm94cGxvdHMgKG1heSBwcm92aWRlIHNvbWUgbW9yZSB1c2VmdWwgaW5mbykNCg0KdGVtcGVyYXR1cmUNCg0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCR0ZW1wX2RlcHRoIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiVGVtcGVyYXR1cmUgKEtlbHZpbikiLCBtYWluID0gIlRlbXBlcmF0dXJlIGF0IEJhY2tncm91bmQgRGVwdGggcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJGNobF9kZXB0aCB+IGJhY2tncm91bmQkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIkNobG9yb3BoeWxsIENvbmNlbnRyYXRpb25zIChtbW9sLm0tMykiLCBtYWluID0gIkNobG9yb3BoeWxsIGF0IEJhY2tncm91bmQgRGVwdGggcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobG9yb3BoeWxsX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJHNhbGluaXR5X2RlcHRoIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IEJhY2tncm91bmQgRGVwdGggcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbGluaXR5X2JhY2tncm91bmRfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJG8yX2RlcHRoIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiTW9sZSBDb25jZW50cmF0aW9uIG9mIERpc3NvbHZlZCBPeHlnZW4gaW4gU2VhIFdhdGVyIChtbW9sLm0tMykiLCBtYWluID0gIkRpc3NvbHZlZCBPeHlnZW4gYXQgQmFja2dyb3VuZCBEZXB0aCBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbzJfYmFja2dyb3VuZF9ib3hwbG90X2RlcHRfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkbWxwX3N1cmZhY2UgfiBiYWNrZ3JvdW5kJG1vbnRoLCB4bGFiID0gIm1vbnRoIiwgeWxhYiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgKG0pIiwgbWFpbiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgYXQgQmFja2dyb3VuZCBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbWxwX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJHNzaF9zdXJmYWNlIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIsIG1haW4gPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IGF0IEJhY2tncm91bmQgcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NzaF9iYWNrZ3JvdW5kX2JveHBsb3RfZGVwdF9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCR0ZW1wX2RlcHRoIH4gYmFja2dyb3VuZCR5ZWFyLCB4bGFiID0gIlllYXIiLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBCYWNrZ3JvdW5kIERlcHRoIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkY2hsX2RlcHRoIH4gYmFja2dyb3VuZCR5ZWFyLCB4bGFiID0gIlllYXIiLCB5bGFiID0gIkNobG9yb3BoeWxsIENvbmNlbnRyYXRpb25zIChtbW9sLm0tMykiLCBtYWluID0gIkNobG9yb3BoeWxsIGF0IEJhY2tncm91bmQgRGVwdGggcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvY2hsX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkc2FsaW5pdHlfZGVwdGggfiBiYWNrZ3JvdW5kJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IEJhY2tncm91bmQgRGVwdGggcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc2FsaW5pdHlfYmFja2dyb3VuZF9ib3hwbG90X2RlcHRfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRvMl9kZXB0aCB+IGJhY2tncm91bmQkeWVhciwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJNb2xlIENvbmNlbnRyYXRpb24gb2YgRGlzc29sdmVkIE94eWdlbiBpbiBTZWEgV2F0ZXIgKG1tb2wubS0zKSIsIG1haW4gPSAiRGlzc29sdmVkIE94eWdlbiBhdCBCYWNrZ3JvdW5kIERlcHRoIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL294eWdlbl9iYWNrZ3JvdW5kX2JveHBsb3RfZGVwdF95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJG1scCB+IGJhY2tncm91bmQkeWVhciwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgKG0pIiwgbWFpbiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgYXQgQmFja2dyb3VuZCBwZXIgWWVhciIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfYmFja2dyb3VuZF9ib3hwbG90X2RlcHRfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRzc2ggfiBiYWNrZ3JvdW5kJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIsIG1haW4gPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IGF0IEJhY2tncm91bmQgcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc3NoX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkdGVtcF9zdXJmYWNlIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiVGVtcGVyYXR1cmUgKEtlbHZpbikiLCBtYWluID0gIlRlbXBlcmF0dXJlIGF0IEJhY2tncm91bmQgKFN1cmZhY2UpIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy90ZW1wZXJhdHVyZV9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRjaGxfc3VyZmFjZSB+IGJhY2tncm91bmQkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIkNobG9yb3BoeWxsIENvbmNlbnRyYXRpb25zIChtbW9sLm0tMykiLCBtYWluID0gIkNobG9yb3BoeWxsIGF0IEJhY2tncm91bmQgKFN1cmZhY2UpIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9jaGxvcm9waHlsbF9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRzYWxpbml0eV9zdXJmYWNlIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IEJhY2tncm91bmQgKFN1cmZhY2UpIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zYWxpbml0eV9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRvMl9zdXJmYWNlIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiTW9sZSBDb25jZW50cmF0aW9uIG9mIERpc3NvbHZlZCBPeHlnZW4gaW4gU2VhIFdhdGVyIChtbW9sLm0tMykiLCBtYWluID0gIkRpc3NvbHZlZCBPeHlnZW4gYXQgQmFja2dyb3VuZCAoU3VyZmFjZSkgcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX2JhY2tncm91bmRfYm94cGxvdF9zdXJmYWNlX21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJG1scF9zdXJmYWNlIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIChtKSIsIG1haW4gPSAiTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIGF0IEJhY2tncm91bmQgcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL21scF9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRzc2hfc3VyZmFjZSB+IGJhY2tncm91bmQkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIlNlYSBTdXJmYWNlIEhlaWdodCAobSkiLCBtYWluID0gIlNlYSBTdXJmYWNlIEhlaWdodCBhdCBCYWNrZ3JvdW5kIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zc2hfYmFja2dyb3VuZF9ib3hwbG90X3N1cmZhY2VfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkdGVtcF9zdXJmYWNlIH4gYmFja2dyb3VuZCR5ZWFyLCB4bGFiID0gIlllYXIiLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBCYWNrZ3JvdW5kIChTdXJmYWNlKSBwZXIgWWVhciIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy90ZW1wZXJhdHVyZV9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJGNobF9zdXJmYWNlIH4gYmFja2dyb3VuZCR5ZWFyLCB4bGFiID0gIlllYXIiLCB5bGFiID0gIkNobG9yb3BoeWxsIENvbmNlbnRyYXRpb25zIChtbW9sLm0tMykiLCBtYWluID0gIkNobG9yb3BoeWxsIGF0IEJhY2tncm91bmQgKFN1cmZhY2UpIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJHNhbGluaXR5X3N1cmZhY2UgfiBiYWNrZ3JvdW5kJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IEJhY2tncm91bmQgKFN1cmZhY2UpIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbGluaXR5X2JhY2tncm91bmRfYm94cGxvdF9zdXJmYWNlX3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkbzJfc3VyZmFjZSB+IGJhY2tncm91bmQkeWVhciwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJNb2xlIENvbmNlbnRyYXRpb24gb2YgRGlzc29sdmVkIE94eWdlbiBpbiBTZWEgV2F0ZXIgKG1tb2wubS0zKSIsIG1haW4gPSAiRGlzc29sdmVkIE94eWdlbiBhdCBCYWNrZ3JvdW5kIChTdXJmYWNlKSBwZXIgWWVhciIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9veHlnZW5fYmFja2dyb3VuZF9ib3hwbG90X3N1cmZhY2VfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQojIyBjb3JyZWxhdGlvbnMgYmV0d2VlbiBiYWNrZ3JvdW5kIHBvaW50cw0KDQpjaGVjayB0byBzZWUgaWYgdGhlcmUgYXJlIGFueSBjb3JyZWxhdGlvbnMgaW4gdGhlIGVudi4gdmFyaWFibGVzIGZvciB0aGUgYmFja2dyb3VuZCBwb2ludHMNCg0KDQpmaXJzdCBzdWJzZXQgdGhlIGVudi5jb3JyZWxhdGUgY29sdW1ucyAoeW91IGRvbid0IG5lZWQgZXZlcnl0aGluZykNCg0KDQpgYGB7cn0NCmJhY2tncm91bmRfZW52IDwtIHN1YnNldChiYWNrZ3JvdW5kLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCkpDQpiYWNrZ3JvdW5kX2Vudl9jb3IgPC0gY29yKGJhY2tncm91bmRfZW52LCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihiYWNrZ3JvdW5kX2Vudl9jb3IsICIuLi9vdXRwdXQvZW52L2JhY2tncm91bmRfZW52X2NvcnIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCmJhY2tncm91bmRfY29ycnBsb3QgPC0gY29ycnBsb3QoYmFja2dyb3VuZF9lbnZfY29yICwgbWV0aG9kID0gImNvbG9yIiwgdHlwZSA9ICJ1cHBlciIsIG9yZGVyID0gImFscGhhYmV0IiwgdGwuY2V4ID0gMC44KSANCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvYmFja2dyb3VuZF9lbnZjb3JyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCnRvIGdldCBzb21lIGRlbnNpdHkgcGxvdHMgYWxsIGluIG9uZSBncmFwaGljLCB5b3UgbmVlZCB0byBjaGFuZ2UgY2h1bmsgb3V0cHV0IHRvIGluIGNvbnNvbGUsIHRoZW4gZ28gdG8gdGhlIHBsb3QgdGFiLCBtYWtlIGl0IGZpbGwgdGhlIHNjcmVlbiwgdGhlbiBydW4gdGhlbiBtYWtlIGJpZ2dlciB0aGVuIHNhdmUgOiggKHByb2JhYmx5IGEgYmV0dGVyIHdheSAtIHRoaXMgc2VlbXMgdG8gYmUgYW4gaXNzdWUgd2l0aCBSU3R1ZGlvKQ0KYGBge3J9DQpwYXIobWZyb3c9Yyg0LDQpKQ0KZm9yKGkgaW4gMToxNil7DQogIHBsb3QoZGVuc2l0eShiYWNrZ3JvdW5kX2VudlssaV0sIG5hLnJtPVQpLCBtYWluID0gbmFtZXMoYmFja2dyb3VuZF9lbnYpW2ldKQ0KfQ0KYGBgDQpQVVQgVEhFIENIVU5LIE9VVFBVVCBCQUNLIFRPIElOTElORQ0KDQoNCmFkZCBuYWZvIHJlZ2lvbiBhbmQgZ2VhciB0eXBlIGludG8gdGhlIG1peCBDQU5UISENCg0KDQpmaXJzdCBzdWJzZXQgdGhlIGVudi5jb3JyZWxhdGUgY29sdW1ucyArIGJvdHRvbV9kZXB0aCAoeW91IGRvbid0IG5lZWQgZXZlcnl0aGluZykNCg0KYGBge3J9DQpiYWNrZ3JvdW5kX2VudmJvdGRlcHRoIDwtIHN1YnNldChiYWNrZ3JvdW5kLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCwgYm90dG9tX2RlcHRoKSkNCmJhY2tncm91bmRfZW52Ym90ZGVwdGhfY29yIDwtIGNvcihiYWNrZ3JvdW5kX2VudmJvdGRlcHRoLCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihiYWNrZ3JvdW5kX2VudmJvdGRlcHRoX2NvciwgIi4uL291dHB1dC9lbnYvYmFja2dyb3VuZF9lbnZib3RkZXB0aF9jb3IuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCmJhY2tncm91bmRfY29ycnBsb3QgPC0gY29ycnBsb3QoYmFja2dyb3VuZF9lbnZib3RkZXB0aF9jb3IgLCBtZXRob2QgPSAiY29sb3IiLCB0eXBlID0gInVwcGVyIiwgb3JkZXIgPSAiYWxwaGFiZXQiLCB0bC5jZXggPSAwLjgpIA0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9iYWNrZ3JvdW5kX2VudmJvdGRlcHRoX2Nvci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQoNCiMjIGNvcnJlbGF0aW9ucyBiZXR3ZWVuIHByZXNlbmNlIHBvaW50cw0KDQpjaGVjayB0byBzZWUgaWYgdGhlcmUgYXJlIGFueSBjb3JyZWxhdGlvbnMgaW4gdGhlIGVudi4gdmFyaWFibGVzDQoNCmZpcnN0IHN1YnNldCB0aGUgZW52LmNvcnJlbGF0ZSBjb2x1bW5zICh5b3UgZG9uJ3QgbmVlZCBldmVyeXRoaW5nKSB0aGVuIHVzZSBjb3IgdG8gZ2V0IHRoZSBjb3JyZWxhdGlvbiB2YWx1ZXMsIGFuZCB0aGVuIGNvcnJwbG90IGZvciBhIHZpc3VhbA0KDQpgYGB7cn0NCnByZXNfZW52IDwtIHN1YnNldChwcmVzZW5jZSwgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgsIGJvdHRvbV9kZXB0aCkpDQpwcmVzX2Vudl9jb3IgPC0gY29yKHByZXNfZW52LCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihwcmVzX2Vudl9jb3IsICIuLi9vdXRwdXQvZW52L3ByZXNfZW52X2NvcnIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnByZXNfY29ycnBsb3QgPC0gY29ycnBsb3QocHJlc19lbnZfY29yICwgbWV0aG9kID0gImNvbG9yIiwgdHlwZSA9ICJ1cHBlciIsIG9yZGVyID0gImFscGhhYmV0IiwgdGwuY2V4ID0gMC44KSANCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvcHJlc19lbnZjb3JyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCnRvIGdldCBzb21lIGRlbnNpdHkgcGxvdHMgYWxsIGluIG9uZSBncmFwaGljLCB5b3UgbmVlZCB0byBjaGFuZ2UgY2h1bmsgb3V0cHV0IHRvIGluIGNvbnNvbGUsIHRoZW4gZ28gdG8gdGhlIHBsb3QgdGFiLCBtYWtlIGl0IGZpbGwgdGhlIHNjcmVlbiwgdGhlbiBydW4gdGhlbiBtYWtlIGJpZ2dlciB0aGVuIHNhdmUgOiggKHByb2JhYmx5IGEgYmV0dGVyIHdheSAtIHRoaXMgc2VlbXMgdG8gYmUgYW4gaXNzdWUgd2l0aCBSU3R1ZGlvKQ0KYGBge3J9DQpwYXIobWZyb3c9Yyg0LDQpKQ0KZm9yKGkgaW4gMToxNil7DQogIHBsb3QoZGVuc2l0eShwcmVzX2VudlssaV0sIG5hLnJtPVQpLCBtYWluID0gbmFtZXMocHJlc19lbnYpW2ldKQ0KfQ0KYGBgDQpQVVQgVEhFIENIVU5LIE9VVFBVVCBCQUNLIFRPIElOTElORQ0KDQoNCiMjIGRlbnNpdHkgcGxvdCB3aXRoIGJhY2tncm91bmQgYW5kIHByZXNlbmNlIGVudi4gZGF0YQ0KDQpJbnNwaXJlZCBieSBNZXJyb3cgMjAxMyAtIHRvcCBwYXJhZ3JhcGggb2YgcGFnZSAxMDYzIChhcmUgdGhlIHNwZWNpZXMgb2JzZXJ2YXRpb25zIHVuaWZvcm1seSBkaXN0cmlidXRlZCBvdmVyIHRoZSBiYWNrZ3JvdW5kLCBvciBhcmUgdGhleSBza2V3ZWQpDQoNCmBgYHtyfQ0KZ2dwbG90KHByZXNfZW52LCBhZXMoeCA9IHRlbXBfZGVwdGgpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJyZWQiKSArIGdlb21fZGVuc2l0eShkYXRhPWJhY2tncm91bmRfZW52LCBuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJibHVlIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcF9kZXB0aF9iYWNrdnNwcmVzLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KHByZXNfZW52LCBhZXMoeCA9IHRlbXBfc3VyZmFjZSkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSwgY29sb3VyID0gInJlZCIpICsgZ2VvbV9kZW5zaXR5KGRhdGE9YmFja2dyb3VuZF9lbnYsIG5hLnJtID0gVFJVRSwgY29sb3VyID0gImJsdWUiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy90ZW1wX3N1cmZhY2VfYmFja3ZzcHJlcy5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChwcmVzX2VudiwgYWVzKHggPSBjaGxfc3VyZmFjZSkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSwgY29sb3VyID0gInJlZCIpICsgZ2VvbV9kZW5zaXR5KGRhdGE9YmFja2dyb3VuZF9lbnYsIG5hLnJtID0gVFJVRSwgY29sb3VyID0gImJsdWUiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9jaGxfc3VyZmFjZV9iYWNrdnNwcmVzLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KHByZXNfZW52LCBhZXMoeCA9IGNobF9kZXB0aCkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSwgY29sb3VyID0gInJlZCIpICsgZ2VvbV9kZW5zaXR5KGRhdGE9YmFja2dyb3VuZF9lbnYsIG5hLnJtID0gVFJVRSwgY29sb3VyID0gImJsdWUiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9jaGxfZGVwdGhfYmFja3ZzcHJlcy5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChwcmVzX2VudiwgYWVzKHggPSBzYWxpbml0eV9zdXJmYWNlKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFLCBjb2xvdXIgPSAicmVkIikgKyBnZW9tX2RlbnNpdHkoZGF0YT1iYWNrZ3JvdW5kX2VudiwgbmEucm0gPSBUUlVFLCBjb2xvdXIgPSAiYmx1ZSIpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbGluaXR5X3N1cmZhY2VfYmFja3ZzcHJlcy5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChwcmVzX2VudiwgYWVzKHggPSBzYWxpbml0eV9kZXB0aCkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSwgY29sb3VyID0gInJlZCIpICsgZ2VvbV9kZW5zaXR5KGRhdGE9YmFja2dyb3VuZF9lbnYsIG5hLnJtID0gVFJVRSwgY29sb3VyID0gImJsdWUiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zYWxpbml0eV9kZXB0aF9iYWNrdnNwcmVzLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KHByZXNfZW52LCBhZXMoeCA9IG8yX3N1cmZhY2UpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJyZWQiKSArIGdlb21fZGVuc2l0eShkYXRhPWJhY2tncm91bmRfZW52LCBuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJibHVlIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbzJfc3VyZmFjZV9iYWNrdnNwcmVzLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KHByZXNfZW52LCBhZXMoeCA9IG8yX2RlcHRoKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFLCBjb2xvdXIgPSAicmVkIikgKyBnZW9tX2RlbnNpdHkoZGF0YT1iYWNrZ3JvdW5kX2VudiwgbmEucm0gPSBUUlVFLCBjb2xvdXIgPSAiYmx1ZSIpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX2RlcHRoX2JhY2t2c3ByZXMucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QocHJlc19lbnYsIGFlcyh4ID0gbWxwX3N1cmZhY2UpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJyZWQiKSArIGdlb21fZGVuc2l0eShkYXRhPWJhY2tncm91bmRfZW52LCBuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJibHVlIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbWxwX2JhY2t2c3ByZXMucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QocHJlc19lbnYsIGFlcyh4ID0gc3NoX3N1cmZhY2UpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJyZWQiKSArIGdlb21fZGVuc2l0eShkYXRhPWJhY2tncm91bmRfZW52LCBuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJibHVlIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc3NoX2JhY2t2c3ByZXMucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KDQojIE5BRk8gUmVnaW9ucw0KDQpjb21wYXJlIHRoZSBlbnZpcm9ubWVudGFsIGNvcnJlbGF0ZXMgYmV0d2VlbiBkaWZmZXJlbnQgTkFGTyByZWdpb25zDQoNCmZpcnN0IHNlZSB3aGljaCBuYWZvIHpvbmVzIHdlcmUgc2FtcGxlZCBpbiBlYWNoIHllYXINCmBgYHtyIHByZXNlbmNlIG5hZm8gYnkgeWVhcn0NCnByZXNlbmNlJG5hZm9fem9uZSA8LSBhcy5jaGFyYWN0ZXIocHJlc2VuY2UkbmFmb196b25lKQ0KbmFmb19ieV95ciA8LSB3aXRoKHByZXNlbmNlLCB0YWJsZSh5ZWFyLCBuYWZvX3pvbmUpKQ0Kd3JpdGUuY3N2KG5hZm9fYnlfeXIsIGZpbGUgPSAiLi4vb3V0cHV0L2Jpby9uYWZvem9uZV9ieV95ci5jc3YiKQ0KbmFmb19ieV95cg0KYGBgDQoNCmFuZCBieSBtb250aA0KYGBge3IgcHJzZW5jZSBuYWZvIGJ5IG1vbnRofQ0KbmFmb19ieV9tdGggPC0gd2l0aChwcmVzZW5jZSwgdGFibGUobmFmb196b25lLCBtb250aCkpDQp3cml0ZS5jc3YobmFmb19ieV9tdGgsIGZpbGUgPSAiLi4vb3V0cHV0L2Jpby9uYWZvem9uZV9ieV9tdGguY3N2IikNCm5hZm9fYnlfbXRoDQpgYGANCg0KSW50ZXJlc3RpbmcgdGhhdCB0aGVyZSBpcyBhIHBvaW50IGluIDFDIC0gdGhpcyBpcyBvdXRzaWRlIENhbmFkaWFuIHdhdGVycyByZW1vdmUgZnJvbSB0aGUgZGF0YXNldA0KYGBge3J9DQpwcmVzYWIgPC0gcHJlc2FiWyEocHJlc2FiJG5hZm9fem9uZSA9PSAiMUMiICYgcHJlc2FiJG9jY3VycmVuY2UgPT0gIjEiKSwgXQ0Kd3JpdGUuY3N2KHByZXNhYiwgIi4uL291dHB1dC9iaW8vcHJlc2FiXzEway5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCnByZXNlbmNlIDwtIHByZXNlbmNlWyEocHJlc2VuY2UkbmFmb196b25lID09ICIxQyIpLCBdDQpgYGANCg0KYW5kIGJ5IG1vbnRoIGFnYWluDQpgYGB7ciBwcnNlbmNlIG5hZm8gYnkgbW9udGgyfQ0KbmFmb19ieV9tdGggPC0gd2l0aChwcmVzZW5jZSwgdGFibGUobmFmb196b25lLCBtb250aCkpDQp3cml0ZS5jc3YobmFmb19ieV9tdGgsIGZpbGUgPSAiLi4vb3V0cHV0L2Jpby9uYWZvem9uZV9ieV9tdGguY3N2IikNCm5hZm9fYnlfbXRoDQpgYGANCg0KDQojIyBkZW5zaXR5IHBsb3Qgd2l0aCBiYWNrZ3JvdW5kIGFuZCBwcmVzZW5jZSBlbnYuIGRhdGEgYnkgTkFGTyByZWdpb24NCg0KV2hhdCBJIHdhbnQgdG8gc2VlIGlmIGlmIHRoZXJlIGlzIGEgbWFya2VkIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgZW52LiBjb3JyZWxhdGVzIG9mIHRoZSBwcmVzZW5jZSBwb2ludHMgYmV0d2VlbiBOQUZPIHJlZ2lvbnMuIFRoaXMgaXMgYWxzbyB0byB0cnkgZGVhbCB3aXRoIHNhbXBsaW5nIGJpYXMgKGIvYyB0aGUgd2hvbGUgcmVnaW9uIGlzIG5vdCB1bmlmb3JtbHkgc2FtcGxlZCBpbiBlYWNoIG1vbnRoLCBidXQgcmF0aGVyIG5hZm8gcmVnaW9ucyBoYXZlIGEgc3Ryb25nIG1vbnRoIGJpYXMpDQoNCmZpcnN0IGNyZWF0ZSBOQUZPLXJlZ2lvbiBkYXRhc2V0cw0KDQpgYGB7ciBwcmVzZW5jZSBieSBuYWZvfQ0KbmFmbzBhIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICIwQSIpDQpuYWZvMGIgPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjBCIikNCm5hZm8yZyA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiMkciKQ0KbmFmbzJoIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICIySCIpDQpuYWZvMmogPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjJKIikNCm5hZm8zayA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiM0siKQ0KbmFmbzNsIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICIzTCIpDQpuYWZvM20gPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjNNIikNCm5hZm8zbiA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiM04iKQ0KbmFmbzNvIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICIzTyIpDQpuYWZvM3BzIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICIzUHMiKQ0KbmFmbzRyIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICI0UiIpDQpuYWZvNHMgPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjRTIikNCm5hZm80dCA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiNFQiKQ0KbmFmbzR2biA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiNFZuIikNCm5hZm80dnMgPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjRWcyIpDQpuYWZvNHcgPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjRXIikNCm5hZm80eCA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiNFgiKQ0KbmFmbzV5IDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICI1WSIpDQpuYWZvNXplIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICI1WkUiKQ0KbmFmb2h1ZHNvbiA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiSHVkc29uU3RyYWl0IikNCmBgYA0KDQpwbG90IGJ5IGVhY2ggdmFyaWFibGUsIGxlc3MgM20gKDIgc2FtcGxlcykgYW5kIDV6ZSAoMiBzYW1wbGVzKQ0KYGBge3IgcHJlc2VuY2UgYnkgbmFmbyBieSB2YXJpYWJsZX0NCmdncGxvdChuYWZvMGEsIGFlcyh4ID0gdGVtcF9zdXJmYWNlLCBjb2xvdXIgPSBuYWZvX3pvbmUpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzBiLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJnLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJoLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJqLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNrLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNsLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNvLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNwcywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80ciwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dm4sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR3LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR4LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzV5LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmb2h1ZHNvbiwgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9uYWZvX3Bsb3RzL3RlbXBfc3VyZmFjZV9uYWZvLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QobmFmbzBhLCBhZXMoeCA9IHRlbXBfZGVwdGgsIGNvbG91ciA9IG5hZm9fem9uZSkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMGIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmosIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2ssIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2wsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM28sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM3BzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRyLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dnMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNXksIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvaHVkc29uLCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X25hZm9fcGxvdHMvdGVtcF9kZXB0aF9uYWZvLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QobmFmbzBhLCBhZXMoeCA9IGNobF9zdXJmYWNlLCBjb2xvdXIgPSBuYWZvX3pvbmUpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzBiLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJnLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJoLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJqLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNrLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNsLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNvLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNwcywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80ciwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dm4sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR3LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR4LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzV5LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmb2h1ZHNvbiwgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9uYWZvX3Bsb3RzL2NobF9zdXJmYWNlX25hZm8ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCmdncGxvdChuYWZvMGEsIGFlcyh4ID0gY2hsX2RlcHRoLCBjb2xvdXIgPSBuYWZvX3pvbmUpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzBiLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJnLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJoLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJqLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNrLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNsLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNvLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNwcywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80ciwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dm4sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR3LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR4LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzV5LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmb2h1ZHNvbiwgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9uYWZvX3Bsb3RzL2NobF9kZXB0aF9uYWZvLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QobmFmbzBhLCBhZXMoeCA9IHNhbGluaXR5X3N1cmZhY2UsIGNvbG91ciA9IG5hZm9fem9uZSkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMGIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmosIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2ssIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2wsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM28sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM3BzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRyLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dnMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNXksIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvaHVkc29uLCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X25hZm9fcGxvdHMvc2FsaW5pdHlfc3VyZmFjZV9uYWZvLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QobmFmbzBhLCBhZXMoeCA9IHNhbGluaXR5X2RlcHRoLCBjb2xvdXIgPSBuYWZvX3pvbmUpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzBiLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJnLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJoLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJqLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNrLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNsLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNvLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNwcywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80ciwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dm4sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR3LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR4LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzV5LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmb2h1ZHNvbiwgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9uYWZvX3Bsb3RzL3NhbGluaXR5X2RlcHRoX25hZm8ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCmdncGxvdChuYWZvMGEsIGFlcyh4ID0gbzJfc3VyZmFjZSwgY29sb3VyID0gbmFmb196b25lKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8wYiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yZywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zaywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zcHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80eCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm81eSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm9odWRzb24sIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfbmFmb19wbG90cy9vMl9zdXJmYWNlX25hZm8ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCmdncGxvdChuYWZvMGEsIGFlcyh4ID0gbzJfZGVwdGgsIGNvbG91ciA9IG5hZm9fem9uZSkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMGIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmosIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2ssIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2wsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM28sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM3BzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRyLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dnMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNXksIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvaHVkc29uLCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X25hZm9fcGxvdHMvbzJfZGVwdGhfbmFmby5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KG5hZm8wYSwgYWVzKHggPSBtbHBfc3VyZmFjZSwgY29sb3VyID0gbmFmb196b25lKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8wYiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yZywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zaywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zcHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80eCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm81eSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm9odWRzb24sIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfbmFmb19wbG90cy9tbHBfbmFmby5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KG5hZm8wYSwgYWVzKHggPSBzc2hfc3VyZmFjZSwgY29sb3VyID0gbmFmb196b25lKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8wYiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yZywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zaywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zcHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80eCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm81eSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm9odWRzb24sIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfbmFmb19wbG90cy9zc2hfbmFmby5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQoNCg0KTGV0J3MgcGxvdCB0aGUgdmFyaWFibGVzIGJ5IG5hZm8gcmVnaW9uL3llYXIgdGhlbiBieSBtb250aA0KDQoNCmBgYHtyfQ0KcHI5OCA8LSBzdWJzZXQocHJlc2VuY2UsIHllYXIgPT0gIjE5OTgiKQ0KYm94cGxvdChwcjk4JHRlbXBfZGVwdGggfiBwcjk4JG5hZm9fem9uZSwgeGxhYiA9ICJOQUZPIFJlZ2lvbiIsIHlsYWIgPSAiVGVtcGVyYXR1cmUgKEtlbHZpbikiLCBtYWluID0gIlRlbXBlcmF0dXJlIGF0IE9ic2VydmF0aW9uIERlcHRoIHBlciBOQUZPIFpvbmUiKQ0KYGBgDQoNCmBgYHtyfQ0KcHI5OCA8LSBzdWJzZXQocHJlc2VuY2UsIHllYXIgPT0gIjE5OTgiKQ0KcHIxMSA8LSBzdWJzZXQocHJlc2VuY2UsIHllYXIgPT0gIjIwMTEiKQ0KcGFyKG1mcm93PWMoMiwxKSkNCmJveHBsb3QocHI5OCR0ZW1wX2RlcHRoIH4gcHI5OCRuYWZvX3pvbmUsIHhsYWIgPSAiTkFGTyBSZWdpb24iLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBPYnNlcnZhdGlvbiBEZXB0aCBwZXIgTkFGTyBab25lIikNCmJveHBsb3QocHIxMSR0ZW1wX2RlcHRoIH4gcHIxMSRuYWZvX3pvbmUsIHhsYWIgPSAiTkFGTyBSZWdpb24iLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBPYnNlcnZhdGlvbiBEZXB0aCBwZXIgTkFGTyBab25lIikNCmBgYA0KDQpvayBzY3JhcCB0aGUgbmFmbyByZWdpb24gYW5hbHlzaXMgLSBpdCBpcyB0b28gbWl4ZWQgdXAgd2l0aCBtb250aCAoc28gc2VlaW5nIGlmIHJlZ2lvbiBvciBtb250aCBpcyBhIGZhY3RvciB0aGF0IG5lZWRzIHRvIGJlIGZhY3RvcmVkIGluIHRvIHRoZSBtb2RlbCBpcyBub3QgYXBwcm9wcmlhdGUpDQoNCiMgcmVtYXAgd2hvIHNhbXBsZWQNCg0KTm93IGxldHMgY2hlY2sgdGhlIG51bWJlciBvZiByZWNvcmRzIGFuZCBzcGF0aWFsLXRlbXBvcmFsIGRpc3RyaWJ1dGlvbiBvZiB0aGUgb2JzZXJ2YXRpb25zIGJ5IGluc3RpdHV0aW9uIGNvZGUgdG8gbWFrZSBzdXJlIG5vbmUgYXJlIGRvZGd5DQoNCmZpcnN0IGEgdGFibGUgb2YgaG93IG1hbnkgb2JzZXJ2YXRpb25zIGVhY2ggaW5zdGl0dWlvbmNvZGUgaGFzDQpgYGB7ciBpbnN0aXR1dGlvbiBjb2RlIGFuYWx5c2lzIC0gY291bnR9DQpvYnNfYnlfaW5zIDwtIGNvdW50KHByZXNlbmNlLCAiaW5zdGl0dXRpb25jb2RlIikNCm9ic19ieV9pbnMNCndyaXRlLmNzdihvYnNfYnlfaW5zLCBmaWxlID0gIi4uL291dHB1dC9iaW8vc2FtcGxpbmdpbnN0aXR1dGlvbnMvbm9fb2JzZXJ2YXRpb25zX2luc3RpdHV0aW9uY29kZS5jc3YiKQ0KYGBgDQpvayBzbyBORUZTQyBhbmQgUk9NIG9ubHkgaGF2ZSBvbmUgcG9pbnQgZWFjaA0KDQpMZXRzIHRha2UgYSBsb29rIGF0IHRoZSBzcGF0aWFsIGJyZWFrZG93biBvZiB0aGVzZSBpbnN0aXR1dGlvbnMuRmlyc3QgYWxsIHBvaW50cy4uLg0KDQpgYGB7cn0NCm1hcDIgPC0gZ2V0TWFwKHJlc29sdXRpb24gPSAibG93IikgI2NyZWF0ZXMgYW4gb2JqZWN0IGNhbGxlZCBtYXAgYXQgbG93IHJlc291bHRpb24NCnBsb3QobWFwMiwgeGxpbSA9IGMoLTcwLCAtNDMpLCB5bGltID1jKDM4LCA3MCksIGFzcCA9IDEsIG1haW4gPSAiQWxsIE9jY3VycmVuY2VzIiwgY29sID0gImNvcm5zaWxrIikgI3RoZSB4IGFuZCB5IGxpbSBhcmUgdGhlIGxvbmctbGF0IGJvdW5kcyBvZiB0aGUgbWFwDQpwb2ludHMocHJlc2VuY2UkZGVjaW1hbExvbmdpdHVkZSwgcHJlc2VuY2UkZGVjaW1hbExhdGl0dWRlLCBjb2wgPSAicmVkIikgI3RoaXMgYWRkcyBwb2ludHMgdG8gdGhlIG1hcGV0IiwgeGxhYiA9ICJMb25naXR1ZGUiLCB5bGFiID0gIkxhdGl0dWRlIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9iaW8vc2FtcGxpbmdpbnN0aXR1dGlvbnMvYWxsX29jY3VycmVuY2VzLnBuZyIpICN0aGlzIHByaW50cyBhIHBuZyBvZiB0aGUgcGxvdA0KZGV2Lm9mZigpICN0aGlzIHR1cm5zIG9mZiB0aGUgcHJpbnQgY29tbWFuZA0KYGBgDQpOb3RlIHRoZXJlIGlzIG9uZSBwb2ludCB1cCBieSBpY2VsYW5kIHRoYXQgeW91IHNob3VsZCBnZXQgcmlkIG9mIChJY2VsYW5kaWMgcG9wdWxhdGlvbiB0aG91Z2h0IHRvIGJlIHNlcGVyYXRlIGZyb20gTGFicmFkb3IsIGJ1dCBpdCBpcyB1bmNsZWFyIGlmIHRoaXMgaXMgdHJ1ZSBvciBub3QpLg0KDQpNYXAgdGhlIGluc3RpdHV0aW9uY29kZSA9PSBBUkMgb25seSBkYXRhLi4uDQpgYGB7ciBtYXAgb2JzIGJ5IGluc3RpdHV0dWlvbn0NCkFSQ19vYnMgPC0gcHJlc2VuY2VbcHJlc2VuY2UkaW5zdGl0dXRpb25jb2RlID09ICJBUkMiLCBdDQptYXAyIDwtIGdldE1hcChyZXNvbHV0aW9uID0gImxvdyIpICNjcmVhdGVzIGFuIG9iamVjdCBjYWxsZWQgbWFwIGF0IGxvdyByZXNvdWx0aW9uDQpwbG90KG1hcDIsIHhsaW0gPSBjKC03MCwgLTQzKSwgeWxpbSA9YygzOSwgNzApLCBhc3AgPSAxLCBtYWluID0gIkFyYyBPY2N1cnJlbmNlcyIsIGNvbCA9ICJjb3Juc2lsayIpICN0aGUgeCBhbmQgeSBsaW0gYXJlIHRoZSBsb25nLWxhdCBib3VuZHMgb2YgdGhlIG1hcA0KcG9pbnRzKEFSQ19vYnMkZGVjaW1hbExvbmdpdHVkZSwgQVJDX29icyRkZWNpbWFsTGF0aXR1ZGUsIGNvbCA9ICJyZWQiKSAjdGhpcyBhZGRzIHBvaW50cyB0byB0aGUgbWFwZXQiLCB4bGFiID0gIkxvbmdpdHVkZSIsIHlsYWIgPSAiTGF0aXR1ZGUiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Jpby9zYW1wbGluZ2luc3RpdHV0aW9ucy9BUkNfb2NjdXJyZW5jZXNfYWxsLnBuZyIpICN0aGlzIHByaW50cyBhIHBuZyBvZiB0aGUgcGxvdA0KZGV2Lm9mZigpICN0aGlzIHR1cm5zIG9mZiB0aGUgcHJpbnQgY29tbWFuZA0KDQpERk9DRU5BUkNfb2JzIDwtIHByZXNlbmNlW3ByZXNlbmNlJGluc3RpdHV0aW9uY29kZSA9PSAiREZPQ0VOQVJDIiwgXQ0KbWFwMiA8LSBnZXRNYXAocmVzb2x1dGlvbiA9ICJsb3ciKSAjY3JlYXRlcyBhbiBvYmplY3QgY2FsbGVkIG1hcCBhdCBsb3cgcmVzb3VsdGlvbg0KcGxvdChtYXAyLCB4bGltID0gYygtNzAsIC00MyksIHlsaW0gPWMoMzksIDcwKSwgYXNwID0gMSwgbWFpbiA9ICJERk8gQ2VudHJhbCAmIEFyY3RpYyBPY2N1cnJlbmNlcyIsICBjb2wgPSAiY29ybnNpbGsiKSAjdGhlIHggYW5kIHkgbGltIGFyZSB0aGUgbG9uZy1sYXQgYm91bmRzIG9mIHRoZSBtYXANCnBvaW50cyhERk9DRU5BUkNfb2JzJGRlY2ltYWxMb25naXR1ZGUsIERGT0NFTkFSQ19vYnMkZGVjaW1hbExhdGl0dWRlLCBjb2wgPSAicmVkIikgI3RoaXMgYWRkcyBwb2ludHMgdG8gdGhlIG1hcGV0IiwgeGxhYiA9ICJMb25naXR1ZGUiLCB5bGFiID0gIkxhdGl0dWRlIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9iaW8vc2FtcGxpbmdpbnN0aXR1dGlvbnMvREZPQ0VOQVJDX29jY3VycmVuY2VzX2FsbC5wbmciKSAjdGhpcyBwcmludHMgYSBwbmcgb2YgdGhlIHBsb3QNCmRldi5vZmYoKSAjdGhpcyB0dXJucyBvZmYgdGhlIHByaW50IGNvbW1hbmQNCg0KREZPR3VsZl9vYnMgPC0gcHJlc2VuY2VbcHJlc2VuY2UkaW5zdGl0dXRpb25jb2RlID09ICJERk9HdWxmIiwgXQ0KbWFwMiA8LSBnZXRNYXAocmVzb2x1dGlvbiA9ICJsb3ciKSAjY3JlYXRlcyBhbiBvYmplY3QgY2FsbGVkIG1hcCBhdCBsb3cgcmVzb3VsdGlvbg0KcGxvdChtYXAyLCB4bGltID0gYygtNzAsIC00MyksIHlsaW0gPWMoMzksIDcwKSwgYXNwID0gMSwgbWFpbiA9ICJERk8gR3VsZiBPY2N1cnJlbmNlcyIsICBjb2wgPSAiY29ybnNpbGsiKSAjdGhlIHggYW5kIHkgbGltIGFyZSB0aGUgbG9uZy1sYXQgYm91bmRzIG9mIHRoZSBtYXANCnBvaW50cyhERk9HdWxmX29icyRkZWNpbWFsTG9uZ2l0dWRlLCBERk9HdWxmX29icyRkZWNpbWFsTGF0aXR1ZGUsIGNvbCA9ICJyZWQiKSAjdGhpcyBhZGRzIHBvaW50cyB0byB0aGUgbWFwZXQiLCB4bGFiID0gIkxvbmdpdHVkZSIsIHlsYWIgPSAiTGF0aXR1ZGUiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Jpby9zYW1wbGluZ2luc3RpdHV0aW9ucy9ERk9HdWxmX29jY3VycmVuY2VzX2FsbC5wbmciKSAjdGhpcyBwcmludHMgYSBwbmcgb2YgdGhlIHBsb3QNCmRldi5vZmYoKSAjdGhpcyB0dXJucyBvZmYgdGhlIHByaW50IGNvbW1hbmQNCg0KREZPSVNETV9vYnMgPC0gcHJlc2VuY2VbcHJlc2VuY2UkaW5zdGl0dXRpb25jb2RlID09ICJERk9JU0RNIiwgXQ0KbWFwMiA8LSBnZXRNYXAocmVzb2x1dGlvbiA9ICJsb3ciKSAjY3JlYXRlcyBhbiBvYmplY3QgY2FsbGVkIG1hcCBhdCBsb3cgcmVzb3VsdGlvbg0KcGxvdChtYXAyLCB4bGltID0gYygtNzAsIC00MyksIHlsaW0gPWMoMzksIDcwKSwgYXNwID0gMSwgbWFpbiA9ICJERk8gSVNETSBPY2N1cnJlbmNlcyIsICBjb2wgPSAiY29ybnNpbGsiKSAjdGhlIHggYW5kIHkgbGltIGFyZSB0aGUgbG9uZy1sYXQgYm91bmRzIG9mIHRoZSBtYXANCnBvaW50cyhERk9JU0RNX29icyRkZWNpbWFsTG9uZ2l0dWRlLCBERk9JU0RNX29icyRkZWNpbWFsTGF0aXR1ZGUsIGNvbCA9ICJyZWQiKSAjdGhpcyBhZGRzIHBvaW50cyB0byB0aGUgbWFwZXQiLCB4bGFiID0gIkxvbmdpdHVkZSIsIHlsYWIgPSAiTGF0aXR1ZGUiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Jpby9zYW1wbGluZ2luc3RpdHV0aW9ucy9ERk9JU0RNX29jY3VycmVuY2VzX2FsbC5wbmciKSAjdGhpcyBwcmludHMgYSBwbmcgb2YgdGhlIHBsb3QNCmRldi5vZmYoKSAjdGhpcyB0dXJucyBvZmYgdGhlIHByaW50IGNvbW1hbmQNCg0KREZPTVRNU19vYnMgPC0gcHJlc2VuY2VbcHJlc2VuY2UkaW5zdGl0dXRpb25jb2RlID09ICJERk9NVE1TIiwgXQ0KbWFwMiA8LSBnZXRNYXAocmVzb2x1dGlvbiA9ICJsb3ciKSAjY3JlYXRlcyBhbiBvYmplY3QgY2FsbGVkIG1hcCBhdCBsb3cgcmVzb3VsdGlvbg0KcGxvdChtYXAyLCB4bGltID0gYygtNzAsIC00MyksIHlsaW0gPWMoMzksIDcwKSwgYXNwID0gMSwgbWFpbiA9ICJERk8gTWFyaXRpbWVzIE9jY3VycmVuY2VzIiwgIGNvbCA9ICJjb3Juc2lsayIpICN0aGUgeCBhbmQgeSBsaW0gYXJlIHRoZSBsb25nLWxhdCBib3VuZHMgb2YgdGhlIG1hcA0KcG9pbnRzKERGT01UTVNfb2JzJGRlY2ltYWxMb25naXR1ZGUsIERGT01UTVNfb2JzJGRlY2ltYWxMYXRpdHVkZSwgY29sID0gInJlZCIpICN0aGlzIGFkZHMgcG9pbnRzIHRvIHRoZSBtYXBldCIsIHhsYWIgPSAiTG9uZ2l0dWRlIiwgeWxhYiA9ICJMYXRpdHVkZSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvYmlvL3NhbXBsaW5naW5zdGl0dXRpb25zL0RGT01UTVNfb2NjdXJyZW5jZXNfYWxsLnBuZyIpICN0aGlzIHByaW50cyBhIHBuZyBvZiB0aGUgcGxvdA0KZGV2Lm9mZigpICN0aGlzIHR1cm5zIG9mZiB0aGUgcHJpbnQgY29tbWFuZA0KDQpERk9OTF9vYnMgPC0gcHJlc2VuY2VbcHJlc2VuY2UkaW5zdGl0dXRpb25jb2RlID09ICJERk9OTCIsIF0NCm1hcDIgPC0gZ2V0TWFwKHJlc29sdXRpb24gPSAibG93IikgI2NyZWF0ZXMgYW4gb2JqZWN0IGNhbGxlZCBtYXAgYXQgbG93IHJlc291bHRpb24NCnBsb3QobWFwMiwgeGxpbSA9IGMoLTcwLCAtNDMpLCB5bGltID1jKDM5LCA3MCksIGFzcCA9IDEsIG1haW4gPSAiREZPIE5ld2ZvdXVuZGxhbmQgJiBMYWJyYWRvciBPY2N1cnJlbmNlcyIsICBjb2wgPSAiY29ybnNpbGsiKSAjdGhlIHggYW5kIHkgbGltIGFyZSB0aGUgbG9uZy1sYXQgYm91bmRzIG9mIHRoZSBtYXANCnBvaW50cyhERk9OTF9vYnMkZGVjaW1hbExvbmdpdHVkZSwgREZPTkxfb2JzJGRlY2ltYWxMYXRpdHVkZSwgY29sID0gInJlZCIpICN0aGlzIGFkZHMgcG9pbnRzIHRvIHRoZSBtYXBldCIsIHhsYWIgPSAiTG9uZ2l0dWRlIiwgeWxhYiA9ICJMYXRpdHVkZSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvYmlvL3NhbXBsaW5naW5zdGl0dXRpb25zL0RGT05MX29jY3VycmVuY2VzX2FsbC5wbmciKSAjdGhpcyBwcmludHMgYSBwbmcgb2YgdGhlIHBsb3QNCmRldi5vZmYoKSAjdGhpcyB0dXJucyBvZmYgdGhlIHByaW50IGNvbW1hbmQNCg0KREZPUUNfb2JzIDwtIHByZXNlbmNlW3ByZXNlbmNlJGluc3RpdHV0aW9uY29kZSA9PSAiREZPUUMiLCBdDQptYXAyIDwtIGdldE1hcChyZXNvbHV0aW9uID0gImxvdyIpICNjcmVhdGVzIGFuIG9iamVjdCBjYWxsZWQgbWFwIGF0IGxvdyByZXNvdWx0aW9uDQpwbG90KG1hcDIsIHhsaW0gPSBjKC03MCwgLTQzKSwgeWxpbSA9YygzOSwgNzApLCBhc3AgPSAxLCBtYWluID0gIkRGTyBRdWViZWMgT2NjdXJyZW5jZXMiLCAgY29sID0gImNvcm5zaWxrIikgI3RoZSB4IGFuZCB5IGxpbSBhcmUgdGhlIGxvbmctbGF0IGJvdW5kcyBvZiB0aGUgbWFwDQpwb2ludHMoREZPUUNfb2JzJGRlY2ltYWxMb25naXR1ZGUsIERGT1FDX29icyRkZWNpbWFsTGF0aXR1ZGUsIGNvbCA9ICJyZWQiKSAjdGhpcyBhZGRzIHBvaW50cyB0byB0aGUgbWFwZXQiLCB4bGFiID0gIkxvbmdpdHVkZSIsIHlsYWIgPSAiTGF0aXR1ZGUiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Jpby9zYW1wbGluZ2luc3RpdHV0aW9ucy9ERk9RQ19vY2N1cnJlbmNlc19hbGwucG5nIikgI3RoaXMgcHJpbnRzIGEgcG5nIG9mIHRoZSBwbG90DQpkZXYub2ZmKCkgI3RoaXMgdHVybnMgb2ZmIHRoZSBwcmludCBjb21tYW5kDQoNCk1haW5lRE1SX29icyA8LSBwcmVzZW5jZVtwcmVzZW5jZSRpbnN0aXR1dGlvbmNvZGUgPT0gIk1haW5lRE1SIiwgXQ0KbWFwMiA8LSBnZXRNYXAocmVzb2x1dGlvbiA9ICJsb3ciKSAjY3JlYXRlcyBhbiBvYmplY3QgY2FsbGVkIG1hcCBhdCBsb3cgcmVzb3VsdGlvbg0KcGxvdChtYXAyLCB4bGltID0gYygtNzAsIC00MyksIHlsaW0gPWMoMzksIDcwKSwgYXNwID0gMSwgbWFpbiA9ICJNYWluZSBETVIgT2NjdXJyZW5jZXMiLCAgY29sID0gImNvcm5zaWxrIikgI3RoZSB4IGFuZCB5IGxpbSBhcmUgdGhlIGxvbmctbGF0IGJvdW5kcyBvZiB0aGUgbWFwDQpwb2ludHMoTWFpbmVETVJfb2JzJGRlY2ltYWxMb25naXR1ZGUsIE1haW5lRE1SX29icyRkZWNpbWFsTGF0aXR1ZGUsIGNvbCA9ICJyZWQiKSAjdGhpcyBhZGRzIHBvaW50cyB0byB0aGUgbWFwZXQiLCB4bGFiID0gIkxvbmdpdHVkZSIsIHlsYWIgPSAiTGF0aXR1ZGUiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Jpby9zYW1wbGluZ2luc3RpdHV0aW9ucy9NYWluZURNUl9vY2N1cnJlbmNlc19hbGwucG5nIikgI3RoaXMgcHJpbnRzIGEgcG5nIG9mIHRoZSBwbG90DQpkZXYub2ZmKCkgI3RoaXMgdHVybnMgb2ZmIHRoZSBwcmludCBjb21tYW5kDQoNCk5FRlNDX29icyA8LSBwcmVzZW5jZVtwcmVzZW5jZSRpbnN0aXR1dGlvbmNvZGUgPT0gIk5FRlNDIiwgXQ0KbWFwMiA8LSBnZXRNYXAocmVzb2x1dGlvbiA9ICJsb3ciKSAjY3JlYXRlcyBhbiBvYmplY3QgY2FsbGVkIG1hcCBhdCBsb3cgcmVzb3VsdGlvbg0KcGxvdChtYXAyLCB4bGltID0gYygtNzAsIC00MyksIHlsaW0gPWMoMzksIDcwKSwgYXNwID0gMSwgbWFpbiA9ICJORUZTQyBPY2N1cnJlbmNlcyIsICBjb2wgPSAiY29ybnNpbGsiKSAjdGhlIHggYW5kIHkgbGltIGFyZSB0aGUgbG9uZy1sYXQgYm91bmRzIG9mIHRoZSBtYXANCnBvaW50cyhORUZTQ19vYnMkZGVjaW1hbExvbmdpdHVkZSwgTkVGU0Nfb2JzJGRlY2ltYWxMYXRpdHVkZSwgY29sID0gInJlZCIpICN0aGlzIGFkZHMgcG9pbnRzIHRvIHRoZSBtYXBldCIsIHhsYWIgPSAiTG9uZ2l0dWRlIiwgeWxhYiA9ICJMYXRpdHVkZSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvYmlvL3NhbXBsaW5naW5zdGl0dXRpb25zL05FRlNDX29jY3VycmVuY2VzX2FsbC5wbmciKSAjdGhpcyBwcmludHMgYSBwbmcgb2YgdGhlIHBsb3QNCmRldi5vZmYoKSAjdGhpcyB0dXJucyBvZmYgdGhlIHByaW50IGNvbW1hbmQNCg0KUk9NX29icyA8LSBwcmVzZW5jZVtwcmVzZW5jZSRpbnN0aXR1dGlvbmNvZGUgPT0gIlJPTSIsIF0NCm1hcDIgPC0gZ2V0TWFwKHJlc29sdXRpb24gPSAibG93IikgI2NyZWF0ZXMgYW4gb2JqZWN0IGNhbGxlZCBtYXAgYXQgbG93IHJlc291bHRpb24NCnBsb3QobWFwMiwgeGxpbSA9IGMoLTcwLCAtNDMpLCB5bGltID1jKDM5LCA3MCksIGFzcCA9IDEsIG1haW4gPSAiUm95YWwgT250YXJpbyBNdXNldW0gT2NjdXJyZW5jZXMiLCAgY29sID0gImNvcm5zaWxrIikgI3RoZSB4IGFuZCB5IGxpbSBhcmUgdGhlIGxvbmctbGF0IGJvdW5kcyBvZiB0aGUgbWFwDQpwb2ludHMoUk9NX29icyRkZWNpbWFsTG9uZ2l0dWRlLCBST01fb2JzJGRlY2ltYWxMYXRpdHVkZSwgY29sID0gInJlZCIpICN0aGlzIGFkZHMgcG9pbnRzIHRvIHRoZSBtYXBldCIsIHhsYWIgPSAiTG9uZ2l0dWRlIiwgeWxhYiA9ICJMYXRpdHVkZSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvYmlvL3NhbXBsaW5naW5zdGl0dXRpb25zL1JPTV9vY2N1cnJlbmNlc19hbGwucG5nIikgI3RoaXMgcHJpbnRzIGEgcG5nIG9mIHRoZSBwbG90DQpgYGANCg0KIyBjaGVjayBmb3IgZ2VhciB0eXBlDQoNCndoYXQgYXJlIHRoZSB1bmlxdWUgZ2VhciB0eXBlcyB5b3UgaGF2ZSBpbiB5b3VyIHByZXNlbmNlIGRhdGEsIGFuZCBob3cgbWFueT8NCg0KYGBge3Igb2JzZXJ2YXRpb24gYnkgY2VsbCAtIHRvdGFsfQ0KZ2Vhcl9jb3VudCA8LSBjb3VudChwcmVzZW5jZSwgImdlYXIiKQ0Kd3JpdGUuY3N2KGdlYXJfY291bnQsIGZpbGUgPSAiLi4vb3V0cHV0L2Jpby9nZWFyX2NvdW50LmNzdiIpDQpnZWFyX2NvdW50DQpgYGANCg0Kc28gdGhlIHZhc3QgbWFqb3JpdHkgYXJlIHRyYXdscyBvZiBzb21lIHR5cGUuIA0KDQptYXAgdGhlIGdlYXIgdXNhZ2UgaW4gQXJjZ2lzIChnZWFyX3R5cGVfbWFwKQ0KDQpjcmVhdGUgYSB0YWJsZSBvZiBnZWFyIHVzZSBieSBtb250aA0KDQpgYGB7cn0NCmdlYXJieV9tdGggPC0gd2l0aChwcmVzZW5jZSwgdGFibGUoZ2VhciwgbW9udGgpKQ0Kd3JpdGUuY3N2KGdlYXJieV9tdGgsIGZpbGUgPSAiLi4vb3V0cHV0L2Jpby9nZWFyX2J5X210aC5jc3YiKQ0KZ2VhcmJ5X210aA0KYGBgDQoNCldoYXQgSSB3YW50IHRvIHNlZSBpZiBpZiB0aGVyZSBpcyBhIG1hcmtlZCBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGVudi4gY29ycmVsYXRlcyBvZiB0aGUgcHJlc2VuY2UgcG9pbnRzIGJldHdlZW4gZ2VhciB0eXBlIHVzZWQuIFRoaXMgaXMgYWxzbyB0byB0cnkgZGVhbCB3aXRoIGRldGVjdGlvbiBiaWFzIGJldHdlZW4gZ2VhciB0eXBlIChiL2MgdGhlIHdob2xlIHJlZ2lvbiBpcyBub3QgdW5pZm9ybWx5IHNhbXBsZWQgYnkgdGhlIHNhbWUgZ2VhciB0eXBlKQ0KDQpmaXJzdCBjcmVhdGUgZ2VhciBkYXRhc2V0cw0KDQpgYGB7ciBwcmVzZW5jZSBieSBnZWFyfQ0KcHJlc2VuY2UkZ2VhciA8LSBhcy5jaGFyYWN0ZXIocHJlc2VuY2UkZ2VhcikNCmJvdHRvbV90cmF3bCA8LSBzdWJzZXQocHJlc2VuY2UsIGdlYXIgPT0gImJvdHRvbV90cmF3bCIpDQpib3R0b21fdHJhd2xfYWxmcmVkb18wMyA8LSBzdWJzZXQocHJlc2VuY2UsIGdlYXIgPT0gImJvdHRvbV90cmF3bF9hbGZyZWRvXzAzIikNCmJvdHRvbV90cmF3bF9jYW1wZWxlbl8xNCA8LSBzdWJzZXQocHJlc2VuY2UsIGdlYXIgPT0gImJvdHRvbV90cmF3bF9jYW1wZWxlbl8xNCIpDQpib3R0b21fdHJhd2xfY2FtcGVsZW5fMTgwMCA8LSBzdWJzZXQocHJlc2VuY2UsIGdlYXIgPT0gImJvdHRvbV90cmF3bF9jYW1wZWxlbl8xODAwIikNCmJvdHRvbV90cmF3bF9jYW1wZWxlbl8yMSA8LSBzdWJzZXQocHJlc2VuY2UsIGdlYXIgPT0gImJvdHRvbV90cmF3bF9jYW1wZWxlbl8yMSIpDQpib3R0b21fdHJhd2xfY29zbW9zXzI2MDAgPC0gc3Vic2V0KHByZXNlbmNlLCBnZWFyID09ICJib3R0b21fdHJhd2xfY29zbW9zXzI2MDAiKQ0KYm90dG9tX3RyYXdsX3dlc3Rlcm5fSUlBIDwtIHN1YnNldChwcmVzZW5jZSwgZ2VhciA9PSAiYm90dG9tX3RyYXdsX3dlc3Rlcm5fSUlBIikNCnVua25vd24gPC0gc3Vic2V0KHByZXNlbmNlLCBnZWFyID09ICJ1bmtub3duIikNCnZlcnRpY2FsX3BsYW5rdG9uX3RvdyA8LSBzdWJzZXQocHJlc2VuY2UsIGdlYXIgPT0gInZlcnRpY2FsX3BsYW5rdG9uX3RvdyIpDQpgYGANCg0KcGxvdCBieSBlYWNoIHZhcmlhYmxlLCBsZXNzIDNtICgyIHNhbXBsZXMpIDFjIChvbmUgc2FtcGxlKSBhbmQgNXplICh6ZXJvIHNhbXBsZXM/ISkNCmBgYHtyIHByZXNlbmNlIGJ5IGdlYXIgYnkgdmFyaWFibGV9DQpnZ3Bsb3QoYm90dG9tX3RyYXdsLCBhZXMoeCA9IHRlbXBfc3VyZmFjZSwgY29sb3VyID0gZ2VhcikpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfYWxmcmVkb18wMywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xNCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xODAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzIxLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2Nvc21vc18yNjAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX3dlc3Rlcm5fSUlBLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dW5rbm93biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXZlcnRpY2FsX3BsYW5rdG9uX3RvdywgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9nZWFyX3Bsb3RzL3RlbXBfc3VyZmFjZV9nZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QoYm90dG9tX3RyYXdsLCBhZXMoeCA9IHRlbXBfZGVwdGgsIGNvbG91ciA9IGdlYXIpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2FsZnJlZG9fMDMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTgwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8yMSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jb3Ntb3NfMjYwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF93ZXN0ZXJuX0lJQSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXVua25vd24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT12ZXJ0aWNhbF9wbGFua3Rvbl90b3csIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfZ2Vhcl9wbG90cy90ZW1wX2RlcHRoX2dlYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCmdncGxvdChib3R0b21fdHJhd2wsIGFlcyh4ID0gY2hsX3N1cmZhY2UsIGNvbG91ciA9IGdlYXIpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2FsZnJlZG9fMDMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTgwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8yMSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jb3Ntb3NfMjYwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF93ZXN0ZXJuX0lJQSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXVua25vd24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT12ZXJ0aWNhbF9wbGFua3Rvbl90b3csIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfZ2Vhcl9wbG90cy9jaGxfc3VyZmFjZV9nZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QoYm90dG9tX3RyYXdsLCBhZXMoeCA9IGNobF9kZXB0aCwgY29sb3VyID0gZ2VhcikpICArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2FsZnJlZG9fMDMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTgwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8yMSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jb3Ntb3NfMjYwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF93ZXN0ZXJuX0lJQSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXVua25vd24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT12ZXJ0aWNhbF9wbGFua3Rvbl90b3csIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfZ2Vhcl9wbG90cy9jaGxfZGVwdGhfZ2Vhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KGJvdHRvbV90cmF3bCwgYWVzKHggPSBzYWxpbml0eV9zdXJmYWNlLCBjb2xvdXIgPSBnZWFyKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9hbGZyZWRvXzAzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE4MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMjEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY29zbW9zXzI2MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfd2VzdGVybl9JSUEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT11bmtub3duLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dmVydGljYWxfcGxhbmt0b25fdG93LCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X2dlYXJfcGxvdHMvc2FsaW5pdHlfc3VyZmFjZV9nZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QoYm90dG9tX3RyYXdsLCBhZXMoeCA9IHNhbGluaXR5X2RlcHRoLCBjb2xvdXIgPSBnZWFyKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9hbGZyZWRvXzAzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE4MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMjEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY29zbW9zXzI2MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfd2VzdGVybl9JSUEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT11bmtub3duLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dmVydGljYWxfcGxhbmt0b25fdG93LCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X2dlYXJfcGxvdHMvc2FsaW5pdHlfZGVwdGhfZ2Vhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KGJvdHRvbV90cmF3bCwgYWVzKHggPSBvMl9zdXJmYWNlLCBjb2xvdXIgPSBnZWFyKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9hbGZyZWRvXzAzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE4MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMjEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY29zbW9zXzI2MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfd2VzdGVybl9JSUEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT11bmtub3duLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dmVydGljYWxfcGxhbmt0b25fdG93LCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X2dlYXJfcGxvdHMvbzJfc3VyZmFjZV9nZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QoYm90dG9tX3RyYXdsLCBhZXMoeCA9IG8yX2RlcHRoLCBjb2xvdXIgPSBnZWFyKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9hbGZyZWRvXzAzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE4MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMjEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY29zbW9zXzI2MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfd2VzdGVybl9JSUEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT11bmtub3duLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dmVydGljYWxfcGxhbmt0b25fdG93LCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X2dlYXJfcGxvdHMvbzJfZGVwdGhfZ2Vhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KGJvdHRvbV90cmF3bCwgYWVzKHggPSBtbHBfc3VyZmFjZSwgY29sb3VyID0gZ2VhcikpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfYWxmcmVkb18wMywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xNCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xODAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzIxLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2Nvc21vc18yNjAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX3dlc3Rlcm5fSUlBLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dW5rbm93biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXZlcnRpY2FsX3BsYW5rdG9uX3RvdywgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9nZWFyX3Bsb3RzL21scF9nZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QoYm90dG9tX3RyYXdsLCBhZXMoeCA9IHNzaF9zdXJmYWNlLCBjb2xvdXIgPSBnZWFyKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9hbGZyZWRvXzAzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE4MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMjEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY29zbW9zXzI2MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfd2VzdGVybl9JSUEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT11bmtub3duLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dmVydGljYWxfcGxhbmt0b25fdG93LCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X2dlYXJfcGxvdHMvc3NoX2dlYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KDQpgYGB7cn0NCnBhcihtYXI9Yyg3LDUsMSwxKSkNCmJveHBsb3QocHJlc2VuY2UkdGVtcF9kZXB0aCB+IHByZXNlbmNlJGdlYXIsIHlsYWIgPSAiVGVtcGVyYXR1cmUgKEtlbHZpbikiLCBtYWluID0gIlRlbXBlcmF0dXJlIGF0IE9ic2VydmF0aW9uIERlcHRoIGJ5IGdlYXIgdHlwZSIsIGxhcyA9IDIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy90ZW1wZXJhdHVyZV9ib3hwbG90X2RlcHRfZ2Vhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQp3aGF0IGFib3V0IGEga3J1c2thbCB3YWxsYWNlIHRlc3Q/DQoNCmBgYHtyfQ0Ka3J1c2thbC50ZXN0KHByZXNlbmNlJHRlbXBfZGVwdGggfiBwcmVzZW5jZSRnZWFyKQ0KYGBgDQpPayBzbyB0aGVyZSBpcyBhIHN0YXRpc3RpY2FsbHkgc2lnIGRpZmZlcmVuY2Ugc29tZXdoZXJlIGluIHRoZSB0ZW1wIGF0IGRlcHRoIHJlcG9ydGVkIGJ5IHRoZSBnZWFyIHR5cGUgKEtydXNrYWwtV2FsbGlzIGNoaS1zcXVhcmVkID0gMjQ4LjI3LCBkZiA9IDcsIHAtdmFsdWUgPCAyLjJlLTE2KQ0KDQpUbyBzZWUgd2hlcmUgdGhlIGRpZmZlcmVuY2UocykgYXJlIHJ1biBhIER1bm4gdGVzdCBaYXIgKDIwMTApIHN0YXRlcyB0aGF0IHRoZSBEdW5uIHRlc3QgKGluIHRoZSBGU0EgcGFja2FnZSkgaXMgYXBwcm9wcmlhdGUgZm9yIGdyb3VwcyB3aXRoIHVuZXF1YWwgbnVtYmVycyBvZiBvYnNlcnZhdGlvbnMuKFphciwgSi5ILiAyMDEwLiBCaW9zdGF0aXN0aWNhbCBBbmFseXNpcywgNXRoIGVkLiAgUGVhcnNvbiBQcmVudGljZSBIYWxsOiBVcHBlciBTYWRkbGUgUml2ZXIsIE5KLikgaHR0cDovL3Jjb21wYW5pb24ub3JnL3Jjb21wYW5pb24vZF8wNi5odG1sDQoNClNBTSBXSEVOIERVTk4gSVMgSU5TVEFMTEVELCBHTyBUTyBSQ09NUEFOSU9OUy5PUkcgQU5EIExPT0sgRk9SIERVTk4gLSBDSEVDSyBDSFJPTUUgSElTVE9SWSAoUFJPQkFCTFkgVU5ERVIgS1JVU0tBTCBXQUxMSVMpIEFMU08gTUFQIFRIRSBESVNUUklCVVRJT04gT0YgVEhFU0UgR0VBUiBUWVBFUw0KYGBge3J9DQpwYWlyd2lzZS53aWxjb3gudGVzdChwcmVzZW5jZSR0ZW1wX2RlcHRoLCBwcmVzZW5jZSRnZWFyLCBwLmFkaj0nYm9uZmVycm9uaScsIGV4YWN0PUYpDQpgYGANCg0KZHVubiB0ZXN0IA0KYGBge3J9DQpnZWFyX3RlbXBfZGVwdGhkdW5uIDwtIGR1bm5UZXN0KHByZXNlbmNlJHRlbXBfZGVwdGgsIHByZXNlbmNlJGdlYXIsIGxpc3QgPSBUUlVFKQ0KZ2Vhcl90ZW1wX2RlcHRoZHVubg0KDQoNCg0Kd3JpdGUuY3N2KHRhYmxlLCAiLi4vb3V0cHV0L2Vudi9nZWFyX3RlbXBfZGVwdGhkdW5uLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQpgYGANCg0KDQojdmlmDQoNCmZvciB0aGlzIHlvdSBuZWVkIHRoZSBqb2luZWQgZGF0YXNldC4gDQoNCmBgYHtyfQ0KdmlmX2FsbHByZXNhYiA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxwcmVzYWIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxscHJlc2FiLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxscHJlc2FiDQpgYGANCmludGVycHJldCAtIHNlZSBodHRwczovL3N0YXRzLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy83MDY3OS93aGljaC12YXJpYW5jZS1pbmZsYXRpb24tZmFjdG9yLXNob3VsZC1pLWJlLXVzaW5nLXRleHRndmlmLW9yLXRleHRndmlmLzk2NTg0Izk2NTg0DQpUbyBtYWtlIEdWSUZzIGNvbXBhcmFibGUgYWNyb3NzIGRpbWVuc2lvbnMsIHdlIHN1Z2dlc3RlZCB1c2luZyBHVklGXigxLygyKkRmKSksIHdoZXJlIERmIGlzIHRoZSBudW1iZXIgb2YgY29lZmZpY2llbnRzIGluIHRoZSBzdWJzZXQgKHJlZiBmb3ggYW5kIG1vdGV0dGUgMTk5MiBpbiB6b3Rlcm8pDQpvciB0aGUgMiBjb250aW51b3VzIHZhcmlhYmxlcywgR1ZJRsuGKDEvKDIqRGYpKSAod2hpY2ggaXMgYmFzaWNhbGx5IHRoZSBzcXVhcmUgcm9vdCBvZiB0aGUgVklGL0dWSUYgdmFsdWUgYXMgREY9MSkgaXMgdGhlIHByb3BvcnRpb25hbCBjaGFuZ2Ugb2YgdGhlIHN0YW5kYXJkIGVycm9yIGFuZCBjb25maWRlbmNlIGludGVydmFsIG9mIHRoZWlyIGNvZWZmaWNpZW50cyBkdWUgdG8gdGhlIGxldmVsIG9mIGNvbGxpbmVhcml0eS4gVGhlIEdWSUbLhigxLygyKkRmKSkgdmFsdWUgb2YgdGhlIGNhdGVnb3JpY2FsIHZhcmlhYmxlIGlzIGEgc2ltaWxhciBtZWFzdXJlIGZvciB0aGUgcmVkdWN0aW9uIGluIHByZWNpc2lvbiBvZiB0aGUgY29lZmZpY2llbnRzJyBlc3RpbWF0aW9uIGR1ZSB0byBjb2xsaW5lYXJpdHkuIA0KYXBwYXJlbnRseSBpIGp1c3QgbmVlZCB0byBzcXVhcmUgR1ZJRl4oMS8oMipEZikpIGFuZCB0aGVuIHVzZSB0aGUgbm9ybWFsIFZJRiAicnVsZSBvZiB0aHVtYiIuLi4NCg0KYGBge3J9DQp2aWZfYWxscHJlc2FiX3NxIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxscHJlc2FiLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxscHJlc2FiX3NxJEdWSUYyRGZzcSA8LSB2aWZfYWxscHJlc2FiX3NxJEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2FsbHByZXNhYl9zcSwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxwcmVzYWIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxwcmVzYWJfc3ENCmBgYA0KDQpBcyBwZXIgU0xSIHN1Z2dlc3Rpb24sIHJlcnVuIHdpdGhvdXQgZ2Vhcg0KDQpgYGB7ciB2aWYgYWxsIGJ1dCBnZWFyfQ0KdmlmX2FsbGJ1dGdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRnZWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dGdlYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRnZWFyDQpgYGANCnh4DQpBcyBwZXIgU0xSIHN1Z2dlc3Rpb24sIHJlcnVuIHdpdGhvdXQgZ2VhciBhbmQgbW9zdCBoaWdobHkgY29ycmVsYXRlZCB2YXJpYWJsZXMgDQoNCmBgYHtyIHZpZiB3aXRob3V0IGdlYXIgKyBoaWdoIGNvcnJ9DQp2aWZfYWxsYnV0Z2VhcmhpZ2hseWNvcnIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIG1scF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0Z2VhcmhpZ2hseWNvcnIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0Z2VhcmhpZ2hseWNvcnIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRnZWFyaGlnaGx5Y29ycg0KYGBgDQoNCg0KQXMgcGVyIFNMUiBzdWdnZXN0aW9uLCByZXJ1biB3aXRoIGdlYXIgYnV0IHdpdGhvdXQgbW9zdCBoaWdobHkgY29ycmVsYXRlZCB2YXJpYWJsZXMNCg0KYGBge3IgdmlmIGFsbCBidXQgaGlnaCBjb3JyfQ0KdmlmX2FsbGJ1dGhpZ2hseWNvcnIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIG1scF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyICsgZ2VhciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dGhpZ2hseWNvcnIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0aGlnaGx5Y29yci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dGhpZ2hseWNvcnINCg0KdmlmX2FsbGJ1dGhpZ2hseWNvcnJfc3EgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRoaWdobHljb3JyLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGx5Y29ycl9zcSRHVklGMkRmc3EgPC0gdmlmX2FsbGJ1dGhpZ2hseWNvcnJfc3EkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0aGlnaGx5Y29ycl9zcSwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRoaWdobHljb3JyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGx5Y29ycl9zcQ0KYGBgDQoNCm9rIHJlbW92ZSBvbmUgdmFyaWFibGUgYXQgYSB0aW1lIC0gbGVhdmUgZ2VhciBpbg0KDQpyZW1vdmUgYm90dG9tX2RlcHRoDQpgYGB7ciB2aWYgYWxsIGJ1dCBib3RkZXB0aH0NCnZpZl9hbGxidXRib3RfcHJldiA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRib3RfcHJldiwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRib3RfcHJldi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQp2aWZfYWxsYnV0Ym90X3ByZXYgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRib3RfcHJldi5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2FsbGJ1dGJvdF9wcmV2JEdWSUYyRGZzcSA8LSB2aWZfYWxsYnV0Ym90X3ByZXYkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0Ym90X3ByZXYsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0Ym90X3ByZXYuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRib3RfcHJldg0KYGBgDQoNCmFuZCBsZWF2ZSBnZWFyIG91dA0KDQpyZW1vdmUgYm90dG9tX2RlcHRoICsgZ2Vhcg0KYGBge3IgdmlmIGFsbCBidXQgYm90ZGRlcHRoICsgZ2Vhcn0NCnZpZl9hbGxidXRib3RfcHJldmdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRib3RfcHJldmdlYXIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0Ym90X3ByZXZnZWFyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0Ym90X3ByZXZnZWFyDQpgYGANCg0KcmVtb3ZlIGFtb19wcmV2DQpgYGB7ciB2aWYgYWxsIGJ1dCBhbW9wcmV2fQ0KdmlmX2FsbGJ1dGFtb19wcmV2IDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRhbW9fcHJldiwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRhbW9fcHJldi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQp2aWZfYWxsYnV0YW1vX3ByZXYgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRhbW9fcHJldi5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2FsbGJ1dGFtb19wcmV2JEdWSUYyRGZzcSA8LSB2aWZfYWxsYnV0YW1vX3ByZXYkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0YW1vX3ByZXYsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0YW1vX3ByZXYuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRhbW9fcHJldg0KYGBgDQphbmQgbGVhdmUgZ2VhciBvdXQNCg0KcmVtb3ZlIGFtb19wcmV2ICsgZ2Vhcg0KYGBge3IgdmlmIGFsbCBidXQgYW1vcHJldiArIGdlYXJ9DQp2aWZfYWxsYnV0YW1vX3ByZXZnZWFyIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dGFtb19wcmV2Z2VhciwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRhbW9fcHJldmdlYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRhbW9fcHJldmdlYXINCmBgYA0KDQpyZW1vdmUgY2hsX2RlcHRoDQpgYGB7ciB2aWYgYWxsIGJ1dCBjaGxkZXB0aH0NCnZpZl9hbGxidXRjaGxfZGVwdGggPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0Y2hsX2RlcHRoLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dGNobF9kZXB0aC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQp2aWZfYWxsYnV0Y2hsX2RlcHRoIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0Y2hsX2RlcHRoLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0Y2hsX2RlcHRoJEdWSUYyRGZzcSA8LSB2aWZfYWxsYnV0Y2hsX2RlcHRoJEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2FsbGJ1dGNobF9kZXB0aCwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRjaGxfZGVwdGguY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRjaGxfZGVwdGgNCmBgYA0KDQpyZW1vdmUgY2hsX2RlcHRoIGFuZCBnZWFyDQpgYGB7ciB2aWYgYWxsIGJ1dCBjaGxkZXB0aCtnZWFyfQ0KdmlmX2FsbGJ1dGNobF9kZXB0aGdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRjaGxfZGVwdGhnZWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dGNobF9kZXB0aGdlYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRjaGxfZGVwdGhnZWFyDQpgYGANCg0KDQpyZW1vdmUgc3NoX3N1cmZhY2UNCmBgYHtyIHZpZiBhbGwgYnV0IHNzaH0NCnZpZl9hbGxidXRzc2hfc3VyZmFjZSA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0c3NoX3N1cmZhY2UsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0c3NoX3N1cmZhY2UuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KdmlmX2FsbGJ1dHNzaF9zdXJmYWNlIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0c3NoX3N1cmZhY2UuY3N2IiwgaGVhZGVyID0gVFJVRSkNCnZpZl9hbGxidXRzc2hfc3VyZmFjZSRHVklGMkRmc3EgPC0gdmlmX2FsbGJ1dHNzaF9zdXJmYWNlJEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2FsbGJ1dHNzaF9zdXJmYWNlLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dHNzaF9zdXJmYWNlLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0c3NoX3N1cmZhY2UNCmBgYA0KDQpyZW1vdmUgc3NoX3N1cmZhY2UgJiBnZWFyDQpgYGB7ciB2aWYgYWxsIGJ1dCBzc2grZ2Vhcn0NCnZpZl9hbGxidXRzc2hfc3VyZmFjZWdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0c3NoX3N1cmZhY2VnZWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dHNzaF9zdXJmYWNlZ2Vhci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dHNzaF9zdXJmYWNlZ2Vhcg0KYGBgDQoNCnJlbW92ZSBvMl9zdXJmYWNlDQpgYGB7ciB2aWYgYWxsIGJ1dCBvMnN1cmZhY2V9DQp2aWZfYWxsYnV0bzJfc3VyZmFjZSA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dG8yX3N1cmZhY2UsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0bzJfc3VyZmFjZS5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQp2aWZfYWxsYnV0bzJfc3VyZmFjZSA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dG8yX3N1cmZhY2UuY3N2IiwgaGVhZGVyID0gVFJVRSkNCnZpZl9hbGxidXRvMl9zdXJmYWNlJEdWSUYyRGZzcSA8LSB2aWZfYWxsYnV0bzJfc3VyZmFjZSRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9hbGxidXRvMl9zdXJmYWNlLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dG8yX3N1cmZhY2UuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRvMl9zdXJmYWNlDQpgYGANCg0KcmVtb3ZlIG8yX3N1cmZhY2UgJiBnZWFyDQpgYGB7ciB2aWYgYWxsIGJ1dCBvMnN1cmZhY2UrZ2Vhcn0NCnZpZl9hbGxidXRvMl9zdXJmYWNlZ2VhciA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0bzJfc3VyZmFjZWdlYXIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0bzJfc3VyZmFjZWdlYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRvMl9zdXJmYWNlZ2Vhcg0KYGBgDQoNCmFzIHBlciBTTFIgY2hhdCBqYW4gMjM6IA0KDQpyZW1vdmUgc2FsaW5pdHlfc3VyZmFjZSBvbmx5DQpgYGB7ciB2aWYgYWxsIGJ1dCBzYWxzdXJmYWNlfQ0KdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZSA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZSwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRzYWxpbml0eXN1cmZhY2UuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZSA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZS5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZSRHVklGMkRmc3EgPC0gdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZSRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9hbGxidXRzYWxpbml0eXN1cmZhY2UsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0c2FsaW5pdHlzdXJmYWNlLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0c2FsaW5pdHlzdXJmYWNlDQpgYGANCmFuZCB3aXRob3V0IGdlYXINCg0KYGBge3IgdmlmIGFsbCBidXQgc2Fsc3VyZmFjZStnZWFyfQ0KdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZWdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZWdlYXIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0c2FsaW5pdHlzdXJmYWNlZ2Vhci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZWdlYXINCmBgYA0KDQpyZW1vdmUgdGVtcF9zdXJmYWNlIG9ubHkNCmBgYHtyIHZpZiBhbGwgYnV0IHRlbXBzdXJmYWNlfQ0KdmlmX2FsbGJ1dHRlbXBzdXJmYWNlIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dHRlbXBzdXJmYWNlLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dHRlbXBzdXJmYWNlLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCnZpZl9hbGxidXR0ZW1wc3VyZmFjZSA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dHRlbXBzdXJmYWNlLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0dGVtcHN1cmZhY2UkR1ZJRjJEZnNxIDwtIHZpZl9hbGxidXR0ZW1wc3VyZmFjZSRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9hbGxidXR0ZW1wc3VyZmFjZSwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXR0ZW1wc3VyZmFjZS5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dHRlbXBzdXJmYWNlDQoNCnZpZl9hbGxidXR0ZW1wc3VyZmFjZWdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXR0ZW1wc3VyZmFjZWdlYXIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0dGVtcHN1cmZhY2VnZWFyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0dGVtcHN1cmZhY2VnZWFyDQoNCmBgYA0KDQpub3cgcmVtb3ZlIHRlbXBfc3VyZmFjZSBwbHVzIGhpZ2hseSBjb3JyZWxhdGVkDQpgYGB7ciB2aWYgYWxsYnV0IGhpZ2ggY29yciArIHRlbXAgc3VyZmFjZS9nZWFyL25vZ2Vhcn0NCiN3aXRoIGdlYXINCnZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBtbHBfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHN1cmZhY2UuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHN1cmZhY2UgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZSRHVklGMkRmc3EgPC0gdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHN1cmZhY2UkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZSwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZQ0KDQojd2l0aG91dCBnZWFyDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZWdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIG1scF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZWdlYXIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZWdlYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlZ2Vhcg0KYGBgDQoNCm5vdyByZW1vdmUgdGVtcF9zdXJmYWNlIHBsdXMgc2FsaW5pdHlfc3VyZmFjZQ0KYGBge3IgdmlmIGFsbGJ1dCB0ZW1wICsgc2FsaW5pdHkgc3VyZmFjZS9nZWFyL25vZ2Vhcn0NCiN3aXRoIGdlYXINCnZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZSA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCnZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZSA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0dGVtcHNhbHN1cmZhY2UkR1ZJRjJEZnNxIDwtIHZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZSRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZSwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZS5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlDQoNCiN3aXRob3V0IGdlYXINCnZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZWdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlZ2VhciwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZWdlYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZWdlYXINCmBgYA0KDQpub3cgcmVtb3ZlIHRlbXBfc3VyZmFjZSBwbHVzIHNhbGluaXR5X3N1cmZhY2UgKyBoaWdobHkgY29ycmVsYXRlZA0KYGBge3IgdmlmIGFsbGJ1dCBoaWdoIGNvcnIgKyAgdGVtcCArIHNhbGluaXR5IHN1cmZhY2UvZ2Vhci9ub2dlYXJ9DQojd2l0aCBnZWFyDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZSA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBtbHBfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRoaWdoY29ycnRlbXBzYWxzdXJmYWNlLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHNhbHN1cmZhY2UuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHNhbHN1cmZhY2UgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRoaWdoY29ycnRlbXBzYWxzdXJmYWNlLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZSRHVklGMkRmc3EgPC0gdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHNhbHN1cmZhY2UkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZSwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRoaWdoY29ycnRlbXBzYWxzdXJmYWNlLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZQ0KDQojd2l0aG91dCBnZWFyDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZWdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgbWxwX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRoaWdoY29ycnRlbXBzYWxzdXJmYWNlZ2VhciwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRoaWdoY29ycnRlbXBzYWxzdXJmYWNlZ2Vhci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHNhbHN1cmZhY2VnZWFyDQpgYGANCg0KSnVzdCBvdXQgb2YgY3VyaW9zaXR5LCBhIHZpZiB3aWxsIGFsbCBidXQgYnV0IGF0bW9zIGRyaXZlcnMNCg0KYGBge3J9DQp2aWZfYWxsYnV0bmFvYW1vIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRuYW9hbW8sICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0bmFvYW1vLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCnZpZl9hbGxidXRuYW9hbW8gPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRuYW9hbW8uY3N2IiwgaGVhZGVyID0gVFJVRSkNCnZpZl9hbGxidXRuYW9hbW8kR1ZJRjJEZnNxIDwtIHZpZl9hbGxidXRuYW9hbW8kR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0bmFvYW1vLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dG5hb2Ftby5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dG5hb2Ftbw0KYGBgDQpub3QgbXVjaCBkaWZmLi4NCg0KIyBtb250aGx5IHNwZWFybWFucyBjb3JyZWxhdGlvbnMgYW5kIFZJRg0KDQpjdXJpb3VzIC0gZG9lcyBjb3JyZWxhdGlvbnMvdmlmIGFsdGVyIGJldHdlZW4gbW9udGhzPw0KDQpGaXJzdCBzcGxpdCB0aGUgZGF0YXNldCBpbnRvIG1vbnRobHkNCg0KYGBge3Igc3Vic2V0IG1vbnRobHkgcHJlc2FifQ0KcHJlc2FiJGdlYXIgPC0gYXMuY2hhcmFjdGVyKHByZXNhYiRnZWFyKQ0KamFucHJlc2FiIDwtIHN1YnNldChwcmVzYWIsIG1vbnRoID09ICIxIikNCmZlYnByZXNhYiA8LSBzdWJzZXQocHJlc2FiLCBtb250aCA9PSAiMiIpDQptYXJwcmVzYWIgPC0gc3Vic2V0KHByZXNhYiwgbW9udGggPT0gIjMiKQ0KYXBycHJlc2FiIDwtIHN1YnNldChwcmVzYWIsIG1vbnRoID09ICI0IikNCm1heXByZXNhYiA8LSBzdWJzZXQocHJlc2FiLCBtb250aCA9PSAiNSIpDQpqdW5wcmVzYWIgPC0gc3Vic2V0KHByZXNhYiwgbW9udGggPT0gIjYiKQ0KanVscHJlc2FiIDwtIHN1YnNldChwcmVzYWIsIG1vbnRoID09ICI3IikNCmF1Z3ByZXNhYiA8LSBzdWJzZXQocHJlc2FiLCBtb250aCA9PSAiOCIpDQpzZXBwcmVzYWIgPC0gc3Vic2V0KHByZXNhYiwgbW9udGggPT0gIjkiKQ0Kb2N0cHJlc2FiIDwtIHN1YnNldChwcmVzYWIsIG1vbnRoID09ICIxMCIpDQpub3ZwcmVzYWIgPC0gc3Vic2V0KHByZXNhYiwgbW9udGggPT0gIjExIikNCmRlY3ByZXNhYiA8LSBzdWJzZXQocHJlc2FiLCBtb250aCA9PSAiMTIiKQ0KYGBgDQoNCm5vdyBnZXQgdGhlIGJhY2tncm91bmQgcG9pbnRzIGZvciBlYWNoIG1vbnRoIChmb3Igc3BlYXJtYW5zKQ0KYGBge3IgbW9udGhseSBiYWNrZ3JvdW5kIHBvaW50c30NCmphbmJhY2sgPC0gc3Vic2V0KGphbnByZXNhYiwgb2NjdXJyZW5jZSA9PSAiMCIpDQpmZWJiYWNrIDwtIHN1YnNldChmZWJwcmVzYWIsIG9jY3VycmVuY2UgPT0gIjAiKQ0KbWFyYmFjayA8LSBzdWJzZXQobWFycHJlc2FiLCBvY2N1cnJlbmNlID09ICIwIikNCmFwcmJhY2sgPC0gc3Vic2V0KGFwcnByZXNhYiwgb2NjdXJyZW5jZSA9PSAiMCIpDQptYXliYWNrIDwtIHN1YnNldChtYXlwcmVzYWIsIG9jY3VycmVuY2UgPT0gIjAiKQ0KanVuYmFjayA8LSBzdWJzZXQoanVucHJlc2FiLCBvY2N1cnJlbmNlID09ICIwIikNCmp1bGJhY2sgPC0gc3Vic2V0KGp1bHByZXNhYiwgb2NjdXJyZW5jZSA9PSAiMCIpDQphdWdiYWNrIDwtIHN1YnNldChhdWdwcmVzYWIsIG9jY3VycmVuY2UgPT0gIjAiKQ0Kc2VwYmFjayA8LSBzdWJzZXQoc2VwcHJlc2FiLCBvY2N1cnJlbmNlID09ICIwIikNCm9jdGJhY2sgPC0gc3Vic2V0KG9jdHByZXNhYiwgb2NjdXJyZW5jZSA9PSAiMCIpDQpub3ZiYWNrIDwtIHN1YnNldChub3ZwcmVzYWIsIG9jY3VycmVuY2UgPT0gIjAiKQ0KZGVjYmFjayA8LSBzdWJzZXQoZGVjcHJlc2FiLCBvY2N1cnJlbmNlID09ICIwIikNCmBgYA0KDQpydW4gdGhlIGNvcnJlbGF0aW9ucyBvbiBlYWNoIG1vbnRoJ3MgYmFja2dyb3VuZCBwb2ludHMNCg0KYGBge3IgbW9udGhseSBzcGVhcm1hbiBjb3JyZWxhdGlvbnN9DQpqYW5iYWNrIDwtIHN1YnNldChqYW5iYWNrLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCwgYm90dG9tX2RlcHRoKSkNCmphbmJhY2tfY29yIDwtIGNvcihqYW5iYWNrLCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihqYW5iYWNrX2NvciwgIi4uL291dHB1dC9lbnYvamFuYmFja19jb3IuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KZmViYmFjayA8LSBzdWJzZXQoZmViYmFjaywgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgsIGJvdHRvbV9kZXB0aCkpDQpmZWJiYWNrX2NvciA8LSBjb3IoZmViYmFjaywgdXNlPSJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAic3BlYXJtYW4iKSAjbmVlZCB0byBjcmVhdGUgYSBjb3JyZWxhdGlvbiB1c2luZyBjb3IgdG8gcGxvdC4gY29tcGxldGUub2JzIG1lYW5zIG5hLnJtIGluIHRoaXMgcGFja2FnZS4gI3VzaW5nIHNwZWFybWFucyBhcyBzdWl0YWJsZSBmb3Igbm9uLWxpbmVhciByZWxhdGlvbnNoaXBzDQp3cml0ZS5jc3YoZmViYmFja19jb3IsICIuLi9vdXRwdXQvZW52L2ZlYmJhY2tfY29yLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCm1hcmJhY2sgPC0gc3Vic2V0KG1hcmJhY2ssIHNlbGVjdCA9IGMoYW1vX3NhbXBsZSwgYW1vX3dpbnRlciwgYW1vX3ByZXYsIG5hb19zYW1wbGUsIG5hb193aW50ZXIsIG5hb19wcmV2LCBjaGxfc3VyZmFjZSwgY2hsX2RlcHRoLCBtbHBfc3VyZmFjZSwgc3NoX3N1cmZhY2UsIHRlbXBfc3VyZmFjZSwgdGVtcF9kZXB0aCwgbzJfc3VyZmFjZSwgbzJfZGVwdGgsIHNhbGluaXR5X3N1cmZhY2UsIHNhbGluaXR5X2RlcHRoLCBib3R0b21fZGVwdGgpKQ0KbWFyYmFja19jb3IgPC0gY29yKG1hcmJhY2ssIHVzZT0iY29tcGxldGUub2JzIiwgbWV0aG9kID0gInNwZWFybWFuIikgI25lZWQgdG8gY3JlYXRlIGEgY29ycmVsYXRpb24gdXNpbmcgY29yIHRvIHBsb3QuIGNvbXBsZXRlLm9icyBtZWFucyBuYS5ybSBpbiB0aGlzIHBhY2thZ2UuICN1c2luZyBzcGVhcm1hbnMgYXMgc3VpdGFibGUgZm9yIG5vbi1saW5lYXIgcmVsYXRpb25zaGlwcw0Kd3JpdGUuY3N2KG1hcmJhY2tfY29yLCAiLi4vb3V0cHV0L2Vudi9tYXJiYWNrX2Nvci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQphcHJiYWNrIDwtIHN1YnNldChhcHJiYWNrLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCwgYm90dG9tX2RlcHRoKSkNCmFwcmJhY2tfY29yIDwtIGNvcihhcHJiYWNrLCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihhcHJiYWNrX2NvciwgIi4uL291dHB1dC9lbnYvYXByYmFja19jb3IuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KbWF5YmFjayA8LSBzdWJzZXQobWF5YmFjaywgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgsIGJvdHRvbV9kZXB0aCkpDQptYXliYWNrX2NvciA8LSBjb3IobWF5YmFjaywgdXNlPSJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAic3BlYXJtYW4iKSAjbmVlZCB0byBjcmVhdGUgYSBjb3JyZWxhdGlvbiB1c2luZyBjb3IgdG8gcGxvdC4gY29tcGxldGUub2JzIG1lYW5zIG5hLnJtIGluIHRoaXMgcGFja2FnZS4gI3VzaW5nIHNwZWFybWFucyBhcyBzdWl0YWJsZSBmb3Igbm9uLWxpbmVhciByZWxhdGlvbnNoaXBzDQp3cml0ZS5jc3YobWF5YmFja19jb3IsICIuLi9vdXRwdXQvZW52L21heWJhY2tfY29yLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCmp1bmJhY2sgPC0gc3Vic2V0KGp1bmJhY2ssIHNlbGVjdCA9IGMoYW1vX3NhbXBsZSwgYW1vX3dpbnRlciwgYW1vX3ByZXYsIG5hb19zYW1wbGUsIG5hb193aW50ZXIsIG5hb19wcmV2LCBjaGxfc3VyZmFjZSwgY2hsX2RlcHRoLCBtbHBfc3VyZmFjZSwgc3NoX3N1cmZhY2UsIHRlbXBfc3VyZmFjZSwgdGVtcF9kZXB0aCwgbzJfc3VyZmFjZSwgbzJfZGVwdGgsIHNhbGluaXR5X3N1cmZhY2UsIHNhbGluaXR5X2RlcHRoLCBib3R0b21fZGVwdGgpKQ0KanVuYmFja19jb3IgPC0gY29yKGp1bmJhY2ssIHVzZT0iY29tcGxldGUub2JzIiwgbWV0aG9kID0gInNwZWFybWFuIikgI25lZWQgdG8gY3JlYXRlIGEgY29ycmVsYXRpb24gdXNpbmcgY29yIHRvIHBsb3QuIGNvbXBsZXRlLm9icyBtZWFucyBuYS5ybSBpbiB0aGlzIHBhY2thZ2UuICN1c2luZyBzcGVhcm1hbnMgYXMgc3VpdGFibGUgZm9yIG5vbi1saW5lYXIgcmVsYXRpb25zaGlwcw0Kd3JpdGUuY3N2KGp1bmJhY2tfY29yLCAiLi4vb3V0cHV0L2Vudi9qdW5iYWNrX2Nvci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQpqdWxiYWNrIDwtIHN1YnNldChqdWxiYWNrLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCwgYm90dG9tX2RlcHRoKSkNCmp1bGJhY2tfY29yIDwtIGNvcihqdWxiYWNrLCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihqdWxiYWNrX2NvciwgIi4uL291dHB1dC9lbnYvanVsYmFja19jb3IuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KYXVnYmFjayA8LSBzdWJzZXQoYXVnYmFjaywgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgsIGJvdHRvbV9kZXB0aCkpDQphdWdiYWNrX2NvciA8LSBjb3IoYXVnYmFjaywgdXNlPSJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAic3BlYXJtYW4iKSAjbmVlZCB0byBjcmVhdGUgYSBjb3JyZWxhdGlvbiB1c2luZyBjb3IgdG8gcGxvdC4gY29tcGxldGUub2JzIG1lYW5zIG5hLnJtIGluIHRoaXMgcGFja2FnZS4gI3VzaW5nIHNwZWFybWFucyBhcyBzdWl0YWJsZSBmb3Igbm9uLWxpbmVhciByZWxhdGlvbnNoaXBzDQp3cml0ZS5jc3YoYXVnYmFja19jb3IsICIuLi9vdXRwdXQvZW52L2F1Z2JhY2tfY29yLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCnNlcGJhY2sgPC0gc3Vic2V0KHNlcGJhY2ssIHNlbGVjdCA9IGMoYW1vX3NhbXBsZSwgYW1vX3dpbnRlciwgYW1vX3ByZXYsIG5hb19zYW1wbGUsIG5hb193aW50ZXIsIG5hb19wcmV2LCBjaGxfc3VyZmFjZSwgY2hsX2RlcHRoLCBtbHBfc3VyZmFjZSwgc3NoX3N1cmZhY2UsIHRlbXBfc3VyZmFjZSwgdGVtcF9kZXB0aCwgbzJfc3VyZmFjZSwgbzJfZGVwdGgsIHNhbGluaXR5X3N1cmZhY2UsIHNhbGluaXR5X2RlcHRoLCBib3R0b21fZGVwdGgpKQ0Kc2VwYmFja19jb3IgPC0gY29yKHNlcGJhY2ssIHVzZT0iY29tcGxldGUub2JzIiwgbWV0aG9kID0gInNwZWFybWFuIikgI25lZWQgdG8gY3JlYXRlIGEgY29ycmVsYXRpb24gdXNpbmcgY29yIHRvIHBsb3QuIGNvbXBsZXRlLm9icyBtZWFucyBuYS5ybSBpbiB0aGlzIHBhY2thZ2UuICN1c2luZyBzcGVhcm1hbnMgYXMgc3VpdGFibGUgZm9yIG5vbi1saW5lYXIgcmVsYXRpb25zaGlwcw0Kd3JpdGUuY3N2KHNlcGJhY2tfY29yLCAiLi4vb3V0cHV0L2Vudi9zZXBiYWNrX2Nvci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQpvY3RiYWNrIDwtIHN1YnNldChvY3RiYWNrLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCwgYm90dG9tX2RlcHRoKSkNCm9jdGJhY2tfY29yIDwtIGNvcihvY3RiYWNrLCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihvY3RiYWNrX2NvciwgIi4uL291dHB1dC9lbnYvb2N0YmFja19jb3IuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0Kbm92YmFjayA8LSBzdWJzZXQobm92YmFjaywgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgsIGJvdHRvbV9kZXB0aCkpDQpub3ZiYWNrX2NvciA8LSBjb3Iobm92YmFjaywgdXNlPSJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAic3BlYXJtYW4iKSAjbmVlZCB0byBjcmVhdGUgYSBjb3JyZWxhdGlvbiB1c2luZyBjb3IgdG8gcGxvdC4gY29tcGxldGUub2JzIG1lYW5zIG5hLnJtIGluIHRoaXMgcGFja2FnZS4gI3VzaW5nIHNwZWFybWFucyBhcyBzdWl0YWJsZSBmb3Igbm9uLWxpbmVhciByZWxhdGlvbnNoaXBzDQp3cml0ZS5jc3Yobm92YmFja19jb3IsICIuLi9vdXRwdXQvZW52L25vdmJhY2tfY29yLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCmRlY2JhY2sgPC0gc3Vic2V0KGRlY2JhY2ssIHNlbGVjdCA9IGMoYW1vX3NhbXBsZSwgYW1vX3dpbnRlciwgYW1vX3ByZXYsIG5hb19zYW1wbGUsIG5hb193aW50ZXIsIG5hb19wcmV2LCBjaGxfc3VyZmFjZSwgY2hsX2RlcHRoLCBtbHBfc3VyZmFjZSwgc3NoX3N1cmZhY2UsIHRlbXBfc3VyZmFjZSwgdGVtcF9kZXB0aCwgbzJfc3VyZmFjZSwgbzJfZGVwdGgsIHNhbGluaXR5X3N1cmZhY2UsIHNhbGluaXR5X2RlcHRoLCBib3R0b21fZGVwdGgpKQ0KZGVjYmFja19jb3IgPC0gY29yKGRlY2JhY2ssIHVzZT0iY29tcGxldGUub2JzIiwgbWV0aG9kID0gInNwZWFybWFuIikgI25lZWQgdG8gY3JlYXRlIGEgY29ycmVsYXRpb24gdXNpbmcgY29yIHRvIHBsb3QuIGNvbXBsZXRlLm9icyBtZWFucyBuYS5ybSBpbiB0aGlzIHBhY2thZ2UuICN1c2luZyBzcGVhcm1hbnMgYXMgc3VpdGFibGUgZm9yIG5vbi1saW5lYXIgcmVsYXRpb25zaGlwcw0Kd3JpdGUuY3N2KGRlY2JhY2tfY29yLCAiLi4vb3V0cHV0L2Vudi9kZWNiYWNrX2Nvci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KYGBgDQoNClJ1biBhIFZJRiBmb3IgZWFjaCBtb250aCAod2l0aCBhbmQgd2l0aG91dCBnZWFyKQ0KDQpgYGB7ciBtb250aGx5IHZpZiB3aXRoIGFuZCB3aXRob3V0IGdlYXJ9DQoNCg0KI3dpdGggZ2VhciAtIGZvciBqYW4gdGhlcmUgaXMgbm9uZSBiZWNhdXNlIHRoZXJlIGlzIG9ubHkgb25lIGNhdGVnb3J5IG9mIGdlYXINCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9qYW4gPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlLCBkYXRhID0gamFucHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2phbiwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfbm9nZWFyX2phbi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX25vZ2Vhcl9qYW4NCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9mZWIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlLCBkYXRhID0gZmVicHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2ZlYiwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfbm9nZWFyX2ZlYi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX25vZ2Vhcl9mZWINCg0KI3dpdGggZ2Vhcg0KdmlmX2dlYXJfbWFyIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IG1hcnByZXNhYikpDQp3cml0ZS5jc3YodmlmX2dlYXJfbWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX21hci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2dlYXJfbWFyDQoNCnZpZl9nZWFyX21hciA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX21hci5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2dlYXJfbWFyJEdWSUYyRGZzcSA8LSB2aWZfZ2Vhcl9tYXIkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfZ2Vhcl9tYXIsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfbWFyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9tYXINCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9tYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBtYXJwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9ub2dlYXJfbWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9ub2dlYXJfbWFyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX21hcg0KDQojd2l0aCBnZWFyDQp2aWZfZ2Vhcl9hcHIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gYXBycHJlc2FiKSkNCndyaXRlLmNzdih2aWZfZ2Vhcl9hcHIsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfYXByLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9hcHINCg0KdmlmX2dlYXJfYXByIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfYXByLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfZ2Vhcl9hcHIkR1ZJRjJEZnNxIDwtIHZpZl9nZWFyX2FwciRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9nZWFyX2FwciwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9hcHIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX2Fwcg0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX2FwciA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IGFwcnByZXNhYikpDQp3cml0ZS5jc3YodmlmX25vZ2Vhcl9hcHIsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9hcHIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9ub2dlYXJfYXByDQoNCiN3aXRoIGdlYXINCnZpZl9nZWFyX21heSA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBtYXlwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9nZWFyX21heSwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9tYXkuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX21heQ0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX21heSA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IG1heXByZXNhYikpDQp3cml0ZS5jc3YodmlmX25vZ2Vhcl9tYXksICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9tYXkuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9ub2dlYXJfbWF5DQoNCiN3aXRoIGdlYXINCnZpZl9nZWFyX2p1biA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBqdW5wcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9nZWFyX2p1biwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9qdW4uY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX2p1bg0KDQoNCiN3aXRob3V0IGdlYXINCnZpZl9ub2dlYXJfanVuIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0ganVucHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2p1biwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfbm9nZWFyX2p1bi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX25vZ2Vhcl9qdW4NCg0KI3dpdGggZ2Vhcg0KdmlmX2dlYXJfanVsIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IGp1bHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2dlYXJfanVsLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2p1bC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2dlYXJfanVsDQoNCnZpZl9nZWFyX2p1bCA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2p1bC5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2dlYXJfanVsJEdWSUYyRGZzcSA8LSB2aWZfZ2Vhcl9qdWwkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfZ2Vhcl9qdWwsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfanVsLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9qdWwNCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9qdWwgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBqdWxwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9ub2dlYXJfanVsLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9ub2dlYXJfanVsLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2p1bA0KDQojd2l0aCBnZWFyDQp2aWZfZ2Vhcl9hdWcgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gYXVncHJlc2FiKSkNCndyaXRlLmNzdih2aWZfZ2Vhcl9hdWcsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfYXVnLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9hdWcNCg0KdmlmX2dlYXJfYXVnIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfYXVnLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfZ2Vhcl9hdWckR1ZJRjJEZnNxIDwtIHZpZl9nZWFyX2F1ZyRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9nZWFyX2F1ZywgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9hdWcuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX2F1Zw0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX2F1ZyA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IGF1Z3ByZXNhYikpDQp3cml0ZS5jc3YodmlmX25vZ2Vhcl9hdWcsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9hdWcuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9ub2dlYXJfYXVnDQoNCiN3aXRoIGdlYXINCnZpZl9nZWFyX3NlcCA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBzZXBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9nZWFyX3NlcCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9zZXAuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX3NlcA0KDQp2aWZfZ2Vhcl9zZXAgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9zZXAuY3N2IiwgaGVhZGVyID0gVFJVRSkNCnZpZl9nZWFyX3NlcCRHVklGMkRmc3EgPC0gdmlmX2dlYXJfc2VwJEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2dlYXJfc2VwLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX3NlcC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2dlYXJfc2VwDQoNCiN3aXRob3V0IGdlYXINCnZpZl9ub2dlYXJfc2VwIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gc2VwcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX3NlcCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfbm9nZWFyX3NlcC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX25vZ2Vhcl9zZXANCg0KI3dpdGggZ2Vhcg0KdmlmX2dlYXJfb2N0IDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IG9jdHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2dlYXJfb2N0LCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX29jdC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2dlYXJfb2N0DQoNCnZpZl9nZWFyX29jdCA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX29jdC5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2dlYXJfb2N0JEdWSUYyRGZzcSA8LSB2aWZfZ2Vhcl9vY3QkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfZ2Vhcl9vY3QsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfb2N0LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9vY3QNCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9vY3QgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBvY3RwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9ub2dlYXJfb2N0LCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9ub2dlYXJfb2N0LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX29jdA0KDQojd2l0aCBnZWFyDQp2aWZfZ2Vhcl9ub3YgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gbm92cHJlc2FiKSkNCndyaXRlLmNzdih2aWZfZ2Vhcl9ub3YsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfbm92LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9ub3YNCg0KdmlmX2dlYXJfbm92IDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfbm92LmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfZ2Vhcl9ub3YkR1ZJRjJEZnNxIDwtIHZpZl9nZWFyX25vdiRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9nZWFyX25vdiwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9ub3YuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX25vdg0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX25vdiA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IG5vdnByZXNhYikpDQp3cml0ZS5jc3YodmlmX25vZ2Vhcl9ub3YsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9ub3YuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9ub2dlYXJfbm92DQoNCiN3aXRoIGdlYXINCnZpZl9nZWFyX2RlYyA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IGRlY3ByZXNhYikpDQp3cml0ZS5jc3YodmlmX2dlYXJfZGVjLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2RlYy5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2dlYXJfZGVjDQoNCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9kZWMgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBkZWNwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9ub2dlYXJfZGVjLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9ub2dlYXJfZGVjLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2RlYw0KYGBgDQoNCnNwZWFybWFucyBpbmRpY2F0ZXMgY2hsX2RlcHRoLCBtbHBfc3VyZmFjZSwgc3NoX3N1cmZhY2UsIHRlbXBfc3VyZmFjZSwgbzJfc3VyZmFjZSwgc2FsaW5pdHlfc3VyZmFjZSwgYW5kIGJvdHRvbV9kZXB0aCwgYW1vX3ByZXYgKGFuZCBmb3IgSnVuIGFuZCBPY3QgY2hsX3N1cmZhY2U7IGFuZCBmb3IgamFuIGFtb193aW50ZXIsIGFtcG9fcHJldiwgYW1vX3NhbXBsZSwgYW5kIE5BT19wcmV2LCBhbmQgZmViIGFtb193aW50ZXIsIGFtcG9fcHJldiwgYW1vX3NhbXBsZSwgbmFvIHdpbnRlciwgYW5kIE5BT19wcmV2KSBhbGwgIGNvcnJlbGF0ZWQgZXZlcnkgbW9udGguIHJlbW92ZSBmcm9tIGVhY2ggbW9kZWwgYW5kIHJlcnVuDQpSdW4gYSBWSUYgZm9yIGVhY2ggbW9udGggKHdpdGggYW5kIHdpdGhvdXQgZ2VhcikNCg0KYGBge3IgbW9udGhseSB2aWYgd2l0aCBhbmQgd2l0aG91dCBnZWFyIGFuZCBoaWdobHkgY29ycmVsYXRlZH0NCg0KDQojd2l0aCBnZWFyIC0gZm9yIGphbiB0aGVyZSBpcyBub25lIGJlY2F1c2UgdGhlcmUgaXMgb25seSBvbmUgY2F0ZWdvcnkgb2YgZ2Vhcg0KDQoNCiN3aXRob3V0IGdlYXINCnZpZl9ub2dlYXJfY29yX2phbiA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UrIG5hb19zYW1wbGUgKyBuYW9fd2ludGVyLCBkYXRhID0gamFucHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2Nvcl9qYW4sICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9jb3JfamFuLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2Nvcl9qYW4NCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9jb3JfZmViIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSAgKyBuYW9fc2FtcGxlLCBkYXRhID0gZmVicHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2Nvcl9mZWIsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9jb3JfZmViLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2Nvcl9mZWINCg0KI3dpdGggZ2Vhcg0KdmlmX2dlYXJfY29yX21hciA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gbWFycHJlc2FiKSkNCndyaXRlLmNzdih2aWZfZ2Vhcl9jb3JfbWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9tYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KdmlmX2dlYXJfY29yX21hciA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9tYXIuY3N2IiwgaGVhZGVyID0gVFJVRSkNCnZpZl9nZWFyX2Nvcl9tYXIkR1ZJRjJEZnNxIDwtIHZpZl9nZWFyX2Nvcl9tYXIkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfZ2Vhcl9jb3JfbWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9tYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX2Nvcl9tYXINCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9jb3JfbWFyIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IG1hcnByZXNhYikpDQp3cml0ZS5jc3YodmlmX25vZ2Vhcl9jb3JfbWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9ub2dlYXJfY29yX21hci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX25vZ2Vhcl9jb3JfbWFyDQoNCiN3aXRoIGdlYXINCnZpZl9nZWFyX2Nvcl9hcHIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IGFwcnByZXNhYikpDQp3cml0ZS5jc3YodmlmX2dlYXJfY29yX2FwciwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3JfYXByLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCnZpZl9nZWFyX2Nvcl9hcHIgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3JfYXByLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfZ2Vhcl9jb3JfYXByJEdWSUYyRGZzcSA8LSB2aWZfZ2Vhcl9jb3JfYXByJEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2dlYXJfY29yX2FwciwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3JfYXByLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9jb3JfYXByDQoNCiN3aXRob3V0IGdlYXINCnZpZl9ub2dlYXJfY29yX2FwciA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBhcHJwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9ub2dlYXJfY29yX2FwciwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfbm9nZWFyX2Nvcl9hcHIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9ub2dlYXJfY29yX2Fwcg0KDQojd2l0aCBnZWFyDQp2aWZfZ2Vhcl9jb3JfbWF5IDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBtYXlwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9nZWFyX2Nvcl9tYXksICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfY29yX21heS5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX2Nvcl9tYXkgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gbWF5cHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2Nvcl9tYXksICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9jb3JfbWF5LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2Nvcl9tYXkNCg0KI3dpdGggZ2Vhcg0KdmlmX2dlYXJfY29yX2p1biA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0ganVucHJlc2FiKSkNCndyaXRlLmNzdih2aWZfZ2Vhcl9jb3JfanVuLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9qdW4uY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX2Nvcl9qdW4NCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9jb3JfanVuIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IGp1bnByZXNhYikpDQp3cml0ZS5jc3YodmlmX25vZ2Vhcl9jb3JfanVuLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9ub2dlYXJfY29yX2p1bi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX25vZ2Vhcl9jb3JfanVuDQoNCiN3aXRoIGdlYXINCnZpZl9nZWFyX2Nvcl9qdWwgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IGp1bHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2dlYXJfY29yX2p1bCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3JfanVsLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCnZpZl9nZWFyX2Nvcl9qdWwgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3JfanVsLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfZ2Vhcl9jb3JfanVsJEdWSUYyRGZzcSA8LSB2aWZfZ2Vhcl9jb3JfanVsJEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2dlYXJfY29yX2p1bCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3JfanVsLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9jb3JfanVsDQoNCiN3aXRob3V0IGdlYXINCnZpZl9ub2dlYXJfY29yX2p1bCA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBqdWxwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9ub2dlYXJfY29yX2p1bCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfbm9nZWFyX2Nvcl9qdWwuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9ub2dlYXJfY29yX2p1bA0KDQojd2l0aCBnZWFyDQp2aWZfZ2Vhcl9jb3JfYXVnIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBhdWdwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9nZWFyX2Nvcl9hdWcsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfY29yX2F1Zy5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQp2aWZfZ2Vhcl9jb3JfYXVnIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfY29yX2F1Zy5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2dlYXJfY29yX2F1ZyRHVklGMkRmc3EgPC0gdmlmX2dlYXJfY29yX2F1ZyRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9nZWFyX2Nvcl9hdWcsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfY29yX2F1Zy5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2dlYXJfY29yX2F1Zw0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX2Nvcl9hdWcgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gYXVncHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2Nvcl9hdWcsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9jb3JfYXVnLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2Nvcl9hdWcNCg0KI3dpdGggZ2Vhcg0KdmlmX2dlYXJfY29yX3NlcCA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gc2VwcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfZ2Vhcl9jb3Jfc2VwLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9zZXAuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KdmlmX2dlYXJfY29yX3NlcCA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9zZXAuY3N2IiwgaGVhZGVyID0gVFJVRSkNCnZpZl9nZWFyX2Nvcl9zZXAkR1ZJRjJEZnNxIDwtIHZpZl9nZWFyX2Nvcl9zZXAkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfZ2Vhcl9jb3Jfc2VwLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9zZXAuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX2Nvcl9zZXANCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9jb3Jfc2VwIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IHNlcHByZXNhYikpDQp3cml0ZS5jc3YodmlmX25vZ2Vhcl9jb3Jfc2VwLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9ub2dlYXJfY29yX3NlcC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX25vZ2Vhcl9jb3Jfc2VwDQoNCiN3aXRoIGdlYXINCnZpZl9nZWFyX2Nvcl9vY3QgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IG9jdHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2dlYXJfY29yX29jdCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3Jfb2N0LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9jb3Jfb2N0DQoNCnZpZl9nZWFyX2Nvcl9vY3QgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3Jfb2N0LmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfZ2Vhcl9jb3Jfb2N0JEdWSUYyRGZzcSA8LSB2aWZfZ2Vhcl9jb3Jfb2N0JEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2dlYXJfY29yX29jdCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3Jfb2N0LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9jb3Jfb2N0DQoNCiN3aXRob3V0IGdlYXINCnZpZl9ub2dlYXJfY29yX29jdCA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBvY3RwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9ub2dlYXJfY29yX29jdCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfbm9nZWFyX2Nvcl9vY3QuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9ub2dlYXJfY29yX29jdA0KDQojd2l0aCBnZWFyDQp2aWZfZ2Vhcl9jb3Jfbm92IDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBub3ZwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9nZWFyX2Nvcl9ub3YsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfY29yX25vdi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQp2aWZfZ2Vhcl9jb3Jfbm92IDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfY29yX25vdi5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2dlYXJfY29yX25vdiRHVklGMkRmc3EgPC0gdmlmX2dlYXJfY29yX25vdiRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9nZWFyX2Nvcl9ub3YsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfY29yX25vdi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2dlYXJfY29yX25vdg0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX2Nvcl9ub3YgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gbm92cHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2Nvcl9ub3YsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9jb3Jfbm92LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2Nvcl9ub3YNCg0KI3dpdGggZ2Vhcg0KdmlmX2dlYXJfY29yX2RlYyA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gZGVjcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfZ2Vhcl9jb3JfZGVjLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9kZWMuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX2Nvcl9kZWMNCg0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX2Nvcl9kZWMgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gZGVjcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2Nvcl9kZWMsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9jb3JfZGVjLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2Nvcl9kZWMNCmBgYA0KDQppbiB0aGUgcHJlc2VuY2VzLCB3aGljaCByb3dzIGFyZSBtaXNzaW5nIGVpdGhlciB0ZW1wX2RlcHRoLCBzYWxpbml0eV9kZXB0aCwgb3IgbzJfZGVwdGg/DQpgYGB7cn0NCmZtYXRjaCgibzJfZGVwdGgiLCBuYW1lcyhwcmVzZW5jZSkpICMzMg0KZm1hdGNoKCJzYWxpbml0eV9kZXB0aCIsIG5hbWVzKHByZXNlbmNlKSkgIzM0DQpmbWF0Y2goInRlbXBfZGVwdGgiLCBuYW1lcyhwcmVzZW5jZSkpICMzNw0KYGBgDQpgYGB7cn0NCnByZXNlbmNlX3dkZXB0aF9ub28yIDwtIHByZXNlbmNlW2lzLm5hKHByZXNlbmNlJG8yX2RlcHRoKSwgXQ0KbnJvdyhwcmVzZW5jZV93ZGVwdGhfbm9vMikgI2p1c3QgdG8gY2hlY2sgaXQgaGFzIG1hcHBlZA0KcHJlc2VuY2Vfd2RlcHRoX25vc2FsaW5pdHkgPC0gcHJlc2VuY2VbaXMubmEocHJlc2VuY2Ukc2FsaW5pdHlfZGVwdGgpLCBdDQpucm93KHByZXNlbmNlX3dkZXB0aF9ub3NhbGluaXR5KSAjanVzdCB0byBjaGVjayBpdCBoYXMgbWFwcGVkDQpwcmVzZW5jZV93ZGVwdGhfbm90ZW1wIDwtIHByZXNlbmNlW2lzLm5hKHByZXNlbmNlJHRlbXBfZGVwdGgpLCBdDQpucm93KHByZXNlbmNlX3dkZXB0aF9ub3RlbXApICNqdXN0IHRvIGNoZWNrIGl0IGhhcyBtYXBwZWQNCmBgYA0KDQpvayByZW1vdmUgYWxsIHJvd3Mgd2hlcmUgdGVtcF9kZXB0aCBpcyBtaXNzaW5nICgzNzI5IHJvd3MpDQpgYGB7cn0NCnByZXNhYl9taXNzaW5ndmFscyA8LSBwcmVzYWJbIWlzLm5hKHByZXNhYiR0ZW1wX2RlcHRoKSwgXQ0KbnJvdyhwcmVzYWJfbWlzc2luZ3ZhbHMpICMxMjY1NzAgLSBjb3JyZWN0DQpgYGANCmNoZWNrIGZvciBtaXNzaW5nIHZhbHMNCmBgYHtyfQ0KcHJlc2VuY2Vfd2RlcHRoX25vbzIgPC0gcHJlc2FiX21pc3Npbmd2YWxzW2lzLm5hKHByZXNhYl9taXNzaW5ndmFscyRvMl9kZXB0aCksIF0NCm5yb3cocHJlc2VuY2Vfd2RlcHRoX25vbzIpICNqdXN0IHRvIGNoZWNrIGl0IGhhcyBtYXBwZWQNCnByZXNlbmNlX3dkZXB0aF9ub3NhbGluaXR5IDwtIHByZXNhYl9taXNzaW5ndmFsc1tpcy5uYShwcmVzYWJfbWlzc2luZ3ZhbHMkc2FsaW5pdHlfZGVwdGgpLCBdDQpucm93KHByZXNlbmNlX3dkZXB0aF9ub3NhbGluaXR5KSAjanVzdCB0byBjaGVjayBpdCBoYXMgbWFwcGVkDQpwcmVzZW5jZV93ZGVwdGhfbm90ZW1wIDwtIHByZXNhYl9taXNzaW5ndmFsc1tpcy5uYShwcmVzYWJfbWlzc2luZ3ZhbHMkdGVtcF9kZXB0aCksIF0NCm5yb3cocHJlc2VuY2Vfd2RlcHRoX25vdGVtcCkgI2p1c3QgdG8gY2hlY2sgaXQgaGFzIG1hcHBlZA0KYGBgDQpvayBub3cgcmVtb3ZlIHJvdyB3aGVyZSBvMl9kZXB0aCBpcyBtaXNzaW5nDQpgYGB7cn0NCnByZXNhYl9taXNzaW5ndmFscyA8LSBwcmVzYWJfbWlzc2luZ3ZhbHNbIWlzLm5hKHByZXNhYl9taXNzaW5ndmFscyRvMl9kZXB0aCksIF0NCm5yb3cocHJlc2FiX21pc3Npbmd2YWxzKSAjMTI2MzYwIC0gY29ycmVjdA0KYGBgDQpvayBhcyBzdW1tYXJpZXMgb2JzZXJ2YXRpb25zIHBlciBtb250aA0KDQpgYGB7cn0NCnByZXNhYl9taXNzaW5ndmFsc19vYnMgPC0gc3Vic2V0KHByZXNhYl9taXNzaW5ndmFscywgb2NjdXJyZW5jZSA9PSAiMSIpDQpvYnNfYnlfbW9udGggPC0gY291bnQocHJlc2FiX21pc3Npbmd2YWxzX29icywgIm1vbnRoIikNCm9ic19ieV9tb250aA0KYGBgDQoNCmFuZCBiZWZvcmUgaXQgd2FzLi4uDQoNCmBgYHtyfQ0Kb2JzX2J5X21vbnRoX3ByZXMgPC0gY291bnQocHJlc2VuY2UsICJtb250aCIpDQpvYnNfYnlfbW9udGhfcHJlcw0KYGBgDQoNCmp1c3QgY2hlY2sgdGhlIG9icyB0aGF0IHlvdSByZW1vdmVkIChzYXZlZCBhcyBwcmVzZW5jZV9uYS5jc3YpIHRvIHNlZSBpZiB0aGUgcmVwb3J0ZWQgZGVwdGggaXMgZGVlcGVyIHRoYW4gdGhlIGdlYmNvIGRlcnJpdmVkIGJvdHRvbSBkZXB0aA0KDQpgYGB7cn0NCnByZXNlbmNlX25hX2dyZWF0ZXIgPC0gc3Vic2V0KHByZXNlbmNlX05BLCBkZXB0aF9sYXllciA+IGJvdHRvbV9kZXB0aF9nbG9yeXMpDQpwcmVzZW5jZV9uYV9ncmVhdGVyIA0KYGBgDQoNCm9rIHBvdGVudGlhbGx5IGkgbWlnaHQgYmUgYWJsZSB0byBjbGF3IGJhY2sgMTUwIHBvaW50cy4uLmltIG5vdCBzdXJlIGl0cyB3b3J0aCBpdA0KDQojbWF4ZW50Pw0KDQpgYGB7cn0NCmxpYnJhcnkoInJhc3RlciIpDQpsaWJyYXJ5KCJkaXNtbyIpDQpsaWJyYXJ5KCJyZ2VvcyIpDQpgYGANCg0K